<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ubuntu Linux &#187; Разработка под Linux</title>
	<atom:link href="/category/developers/feed/" rel="self" type="application/rss+xml" />
	<link>http://UbuntuLinux.ru</link>
	<description>Сайт для пользователей Ubuntu Linux</description>
	<lastBuildDate>Sat, 25 Oct 2014 15:23:48 +0000</lastBuildDate>
	<language>ru-RU</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.9.1</generator>
	<item>
		<title>Основы работы с потоками в Python</title>
		<link>http://UbuntuLinux.ru/developers/basic-threading-in-python/</link>
		<comments>http://UbuntuLinux.ru/developers/basic-threading-in-python/#comments</comments>
		<pubDate>Mon, 22 Mar 2010 03:57:54 +0000</pubDate>
		<dc:creator><![CDATA[Admin]]></dc:creator>
				<category><![CDATA[Разработка под Linux]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[threads]]></category>

		<guid isPermaLink="false">http://manlinux.org/?p=94</guid>
		<description><![CDATA[Перевод статьи Basic Threading in Python (автор Peyton McCullough), автор перевода Сергей Шилов Если вы желаете, чтобы ваше приложение выполняло несколько задач в одно и то же время, то можете воспользоваться потоками (threads). Python может работать с потоками, но много разработчиков находят программирование &#8230; <a href="/developers/basic-threading-in-python/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><strong>Перевод статьи Basic Threading in Python (автор Peyton McCullough), автор перевода Сергей Шилов</strong></p>
<div id="preamble">
<p>Если вы желаете, чтобы ваше приложение выполняло несколько задач в одно и то же время, то можете воспользоваться потоками (<em>threads</em>). Python может работать с потоками, но много разработчиков находят программирование потоков очень сложным. Среди прочего Peyton McCullough объяснит как порождать и уничтожать потоки в этом популярном языке.</p>
</div>
<p><span id="more-864"></span></p>
<h2>Введение</h2>
<div>
<p>Потоки позволяют приложениям выполнять в одно и то же время множество задач. Многопоточность (<em>multi-threading</em>) важна во множестве приложений, от примитивных серверов до современных сложных и ресурсоёмких игр, так что, естественно, многие языки программирования поддерживают возможность работы с потоками. Python тоже входит в их число.</p>
<p>Однако, поддержка многопоточности в Python не обходится без ограничений и последствий, как писал Гвидо ван Россум:</p>
<div>
<p>«К несчастью, для большинства смертных программирование потоков просто Слишком Сложное, чтобы делать его правильно… Даже в Python — всякий раз, как кто-то всерьёз берётся за программирование потоков, на меня обрушиваются тонны сообщений об ошибках, причём если причиной половины из них действительно являются ошибки в интерпретаторе Python, то причина второй половины кроется в недостаточном понимании особенностей многопоточности…»</p>
</div>
<p>Прежде чем мы приступим к разбору кода, работающего с потоками, нам нужно рассмотреть наиболее важную вещь — глобальную блокировку интерпретатора (<em>global interpreter lock</em>, <em>GIL</em>) Python. Если два или более потока попытаются манипулировать одним и тем же объектом в одно и то же время, то неизбежно возникнут проблемы. Глобальная блокировка интерпретатора исправляет это. В любой момент времени действия может выполнять только один поток. Python автоматически переключается между потоками, когда в этом возникает необходимость.</p>
</div>
<h2>Использование модуля Threading</h2>
<div>
<p>Модуль threading предоставляет нам простой способ работы с потоками. Его класс Thread может быть унаследован (<em>subclassed</em>) для создания потока или нескольких потоков. Метод run должен содержать код, который вы желаете выполнить при выполнении потока. Звучит просто, не так ли? Вот, посмотрите:</p>
<div>
<pre>import threading
class MyThread(threading.Thread):
    def run(self):
        print 'Insert some thread stuff here.'
        print 'It'll be executed...yeah....'
        print 'There's not much to it.'</pre>
</div>
<p>Выполнить поток также просто. Всё, что нам нужно сделать, это создать экземпляр нашего класса потока, после чего вызвать его метод start:</p>
<div>
<pre>import threading
class MyThread(threading.Thread):

    def run(self):
        print 'You called my start method, yeah.'
        print 'Were you expecting something amazing?'

 MyThread().start()</pre>
</div>
<p>Конечно, всего один поток это не бог весть что. Как и люди, потоки через некоторое время остаются в одиночестве. Давайте создадим группу потоков:</p>
<div>
<pre>import threading
theVar = 1
class MyThread(threading.Thread):
    def run ( self ):
        global theVar
        print 'This is thread ' + str(theVar) + ' speaking.'
        print 'Hello and good bye.'
        theVar = theVar + 1

for x in xrange ( 20 ):
    MyThread().start()</pre>
</div>
<p>Давайте теперь сделаем с помощью модуля threading нечто условно-полезное. Сервера часто используют потоки для работы в одно и то же время с несколькими клиентами. Давайте создадим простой, но расширяемый сервер. Когда клиент подключится к нему, сервер создаст новый поток для обслуживания этого клиента. Чтобы отправлять потоку данные клиента нам понадобится перекрыть метод __init__ класса Thread, чтобы он принимал параметры. Отнынесервер будет отправлять поток своей дорогой и ждать новых клиентов. Каждый поток будет посылать упакованный (<em>pickled</em>) объект соответствующему клиенту, после чего печатать не более десяти строк, полученных от клиента. (Упакованный объект в общем случае является объектом, уменьшенным до нескольких символов. Это полезно при сохранении объектов для последующего использования или для передачи объектов по сети).</p>
<div>
<pre>import pickle
import socket
import threading

# We'll pickle a list of numbers:
someList = [1, 2, 7, 9, 0]
pickledList = pickle.dumps(someList)

# Our thread class:
class ClientThread(threading.Thread):

    # Override Thread's __init__ method to accept the parameters needed:
    def __init__(self, channel, details):
        self.channel = channel
        self.details = details
        threading.Thread.__init__(self)

    def run(self):
        print 'Received connection:', self.details[0]
        self.channel.send(pickledList)
        for x in xrange(10):
            print self.channel.recv(1024)
        self.channel.close()
        print 'Closed connection:', self.details[0]

# Set up the server:
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('', 2727))
server.listen(5)

# Have the server serve "forever":
while True:
    channel, details = server.accept()
    ClientThread(channel, details).start()</pre>
</div>
<p>Теперь нам нужно создать клиента, который будет подключаться к серверу, получать от него упакованный объект, распаковывать (<em>reconstructs</em>) объект и, наконец, посылать десять сообщений и закрывать соединение:</p>
<div>
<pre>import pickle
import socket

# Connect to the server:
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('localhost', 2727))

# Retrieve and unpickle the list object:
print pickle.loads(client.recv(1024))

# Send some messages:
for x in xrange(10):
    client.send('Hey. ' + str(x) + 'n')

# Close the connection
client.close()</pre>
</div>
<p>Конечно, приведённый выше клиент не в состоянии воспользоваться всеми преимуществами многопоточностинашего сервера. Клиент порождает только один поток, что делает многопоточность бессмысленной. Давайте добавим клиенту многопоточности, чтобы сделать всё более интересным. Каждый поток будет подключаться ксерверу и выполнять приведённый выше код:</p>
<div>
<pre>import pickle
import socket
import threading

# Here's our thread:
class ConnectionThread(threading.Thread):
    def run(self):
        # Connect to the server:
        client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        client.connect (('localhost', 2727))

        # Retrieve and unpickle the list object:
        print pickle.loads(client.recv(1024))

        # Send some messages:
        for x in xrange(10):
            client.send('Hey. ' + str(x) + 'n')

        # Close the connection
        client.close()

# Let's spawn a few threads:
for x in xrange(5):
    ConnectionThread().start()</pre>
</div>
</div>
<h2>Пулы потоков (<em>pooling threads</em>)</h2>
<div>
<p>Важно помнить, что потоки не появляются мгновенно. Создание большого их числа может замедлить ваше приложение. Чтобы создать поток и, позднее, уничтожить его, требуется время. Потоки могут также потреблять много ценных системных ресурсов в больших приложениях. Эта проблема легко решается путём создания ограниченного числа потоков (<em>set number of threads</em>) (пула потоков) и назначения им новых задач, в общем, повторного их использования. Соединения будут приниматься и передаваться тому потоку, который раньше всех закончит работу с предыдущим клиентом.</p>
<p>Если вы по-прежнему не понимаете, сравните это с больницей. Скажем, у нас есть пятеро врачей. Это наши потоки. Пациенты (клиенты) приходят в больницу и, если врачи заняты, сидят в приёмном покое.</p>
<p>Очевидно, нам нужно нечто, что сможет передавать данные клиента в наши потоки, не вызывая при этом проблем (оно должно быть «потокобезопасным»). Модуль Queue Python делает это для нас. Клиентская информация сохраняется в объекте Queue, откуда потоки извлекают её по мере надобности.</p>
<p>Давайте переделаем наш сервер, чтобы оценить преимущества пула потоков:</p>
<div>
<pre>import pickle
import Queue
import socket
import threading

# We'll pickle a list of numbers, yet again:
someList = [1, 2, 7, 9, 0]
pickledList = pickle.dumps(someList)

# A revised version of our thread class:
class ClientThread(threading.Thread):

# Note that we do not override Thread's __init__ method.
# The Queue module makes this not necessary.

    def run(self):
        # Have our thread serve "forever":
        while True:
            # Get a client out of the queue
            client = clientPool.get()

            # Check if we actually have an actual client in the client variable:
            if client != None:
                print 'Received connection:', client[1][0]
                client[0].send(pickledList)
                for x in xrange(10):
                    print client[0].recv(1024)
                client[0].close()
                print 'Closed connection:', client[1][0]

# Create our Queue:
clientPool = Queue.Queue(0)

# Start two threads:
for x in xrange(2):
    ClientThread().start()
# Set up the server:
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('', 2727))
server.listen(5)

# Have the server serve "forever":
while True:
    clientPool.put(server.accept())</pre>
</div>
<p>Как вы можете увидеть, он немного сложнее нашего предыдущего сервера, но не усложнён до полной непонятности. Для проверки этого сервера, так же, как и предыдущего, можно воспользоваться клиентом из предыдущего раздела.</p>
</div>
<h2>Дополнительные хитрости</h2>
<div>
<p>Работа с потоками не заключается только в их создании и уничтожении. Модуль (может, не модуль а класс?) Thread из модуля threading содержит ещё несколько методов, которые могут вам пригодиться. Первые два предназначены для именования потоков. Метод setName присваивает потоку имя, а метод getName возвращает имя потока:</p>
<div>
<pre>import threading

class TestThread(threading.Thread):
    def run(self):
        print 'Hello, my name is', self.getName()

cazaril = TestThread()
cazaril.setName('Cazaril')
cazaril.start()

ista = TestThread()
ista.setName('Ista')
ista.start()

TestThread().start()</pre>
</div>
<p>Ничего удивительного. Также, как вы можете видеть, у потоков есть имена, даже если вы их не задавали.</p>
<p>Мы также можем проверить, является ли поток «живым», воспользовавшись методом isAlive. Если поток ещё не закончил выполняться, независимо от того, что происходит в его методе run, то он классифицируется как «живой»:</p>
<div>
<pre>import threading
import time

class TestThread(threading.Thread):

    def run(self):
        print 'Patient: Doctor, am I going to die?'

class AnotherThread(TestThread):

    def run (self):
        TestThread.run(self)
        time.sleep(10)

dying = TestThread()
dying.start()
if dying.isAlive():
    print 'Doctor: No.'
else:
    print 'Doctor: Next!'

living = AnotherThread()
living.start()
if living.isAlive():
    print 'Doctor: No.'
else:
    print 'Doctor: Next!'</pre>
</div>
<p>Второй поток остаётся в живых, поскольку мы заставили его ждать, воспользовавшись методом sleep модуля time.</p>
<p>Если нам нужно, чтобы поток дождался завершения другого потока, можно воспользоваться методом join:</p>
<div>
<pre>import threading
import time

class ThreadOne(threading.Thread):

    def run(self):
        print 'Thread', self.getName(), 'started.'
        time.sleep ( 5 )
        print 'Thread', self.getName(), 'ended.'

class ThreadTwo(threading.Thread):

    def run(self):
        print 'Thread', self.getName(), 'started.'
        thingOne.join()
        print 'Thread', self.getName(), 'ended.'

thingOne = ThreadOne()
thingOne.start()
thingTwo = ThreadTwo()
thingTwo.start()</pre>
</div>
<p>Мы также можем использовать метод setDaemon. Если при вызове в него передаётся значение True и другие потоки завершили своё исполнение, то из основной программы будет произведён выход, а поток продолжит работу:</p>
<div>
<pre>import threading
import time

class DaemonThread(threading.Thread):

    def run(self):
        self.setDaemon(True)
        time.sleep(10)

DaemonThread().start()
print 'Leaving.'</pre>
</div>
<p>Python также содержит модуль thread, работающий на более низком уровне, чем threading. Хочу обратить ваше внимание на одну особенность: это содержащаяся в нём функция start_new_thread. Используя её мы можем превратить обычную функцию в поток:</p>
<div>
<pre>import thread

def thread(stuff):
    print "I'm a real boy!"
    print stuff

thread.start_new_thread(thread, ('Argument'))</pre>
</div>
</div>
<h2>Заключение</h2>
<div>
<p>О многопоточности можно рассказать значительно больше, чем я сделал в этой статье, но я не буду пытаться объять необъятное. Кроме того, как упомянул Гвидо ван Россум, преимущества, которые даёт сложная многопоточность вPython могут быть сведены на нет последствиями. Однако, небольшая доза здравого смысла может устранить большинство проблем в простой многопоточности.</p>
<p>Многопоточность очень важна, когда дело касается компьютерных приложений и, как я упоминал раньше, Python её поддерживает. При условии правильного использования, эффект от применения потоков может быть очень благотворным и часто даже критическим, как я подчеркивал в этой статье.</p>
<div>
<div>DISCLAIMER</div>
<p>The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.</p>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://UbuntuLinux.ru/developers/basic-threading-in-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Guitar Pro 4.06 File Format Description (перевод на русский)</title>
		<link>http://UbuntuLinux.ru/developers/protokoly/guitar-pro-4-06-file-format-description-in-russian/</link>
		<comments>http://UbuntuLinux.ru/developers/protokoly/guitar-pro-4-06-file-format-description-in-russian/#comments</comments>
		<pubDate>Sun, 21 Mar 2010 09:55:11 +0000</pubDate>
		<dc:creator><![CDATA[Admin]]></dc:creator>
				<category><![CDATA[Протоколы]]></category>
		<category><![CDATA[gp4]]></category>
		<category><![CDATA[Guitar Pro]]></category>

		<guid isPermaLink="false">http://manlinux.org/?p=80</guid>
		<description><![CDATA[Формат файлов GUITAR PRO v4.06 Версия: 1.0RC1 Русский Автор: Laurent Vromman Переводчик на английский: Avery Ceo, Matthieu Wipliez Переводчик на русский: Бажуков Георгий aka Helios Оглавление I. Основы II. Версии III. Структура файла IV. Заголовки 1. Версия 2. Информация об &#8230; <a href="/developers/protokoly/guitar-pro-4-06-file-format-description-in-russian/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<pre>Формат файлов GUITAR PRO v4.06

Версия:   1.0RC1 Русский
Автор:    Laurent Vromman
Переводчик на английский: Avery Ceo, Matthieu Wipliez
Переводчик на русский: Бажуков Георгий aka Helios
<span id="more-861"></span>
<h2>Оглавление</h2>
I.   <a href="#GENERAL">Основы</a>
	II.  <a href="#VERSIONS">Версии</a>
	III. <a href="#File_Structure">Структура файла</a>
	IV.  <a href="#HEADERS">Заголовки</a>
		 1. <a href="#Version">Версия</a>
		 2. <a href="#Information_About_the_Piece">Информация об отрывке</a>
		 3. <a href="#Lyrics">Текст</a>
		 4. <a href="#Other_information_about_the_piece">Другая информация об отрывке</a>
	V.   <a href="#FILE_BODY">Тело файла</a>
		 1. <a href="#Measures">Измерения</a>
		 2. <a href="#Tracks">Треки</a>
		 3. <a href="#Measures-Tracks_pairs">Пары мер-треков</a>
		 4. <a href="#A_beat">Удары</a>
		 5. <a href="#Chords_diagrams">Диаграммы аккордов</a>
 		 6. <a href="#Effects_on_beats">Эффекты на ударах</a>
 		 7. <a href="#Mix_table_change_event">Смешение таблиц изменения событий</a>
 		 8. <a href="#Note">Ноты</a>
 		 9. <a href="#Effects_on_the_notes">Эффекты для нот</a>
 		 	a. <a href="#Effects_on_the_notes_2">Эффекты для нот</a>
 			b. <a href="#Grace_notes">Украшение нот</a>
 		10. <a href="#Bends">Изгибы</a>
 	VI.  <a href="#CHORDS_DIAGRAMS2">Диаграммы аккордов</a>
<h2>I. Основы</h2>
<a name="integer"></a>Значение типа 'int' занимает 4 байта.
<a name="short_int"></a>Значение типа 'short int' - 2 байта.
Значение типа 'byte' - 1 байт.

Значения типа “integer” и “byte” представленные в этом документе
пишутся с лева не право с LSB (младшего байта)
к MSB (старшему байту).

<a name="color"></a>Цвета хранятся в 4х байтах следующим образом, данные записываются слева направо с
LSB (младший байт), к MSB (старший байт):
    __
3 |__| &lt;- Белый, он всегда 0x00 (альфа-канал?);
2 |__| &lt;- Синий;
1 |__| &lt;- Зелёный;
0 |__| &lt;- Красный.
Когда в этом документе используется термин "строка символов", это означает, пара
первый байт количества 'n' символов в строке (а следовательно строка не должна превышать 255 символов)
затем 'n' самих символов.

Ноты хранится в значении типа <a href="#integer">целое</a>. Значение C(до) = 0. Значение увеличивается на 1 при
увеличении ноты на пол тона:
- C#(0) = 1;
- C (1) = 12;
- E (2) = 28 ...

<a href="#Summary">К оглавлению</a>
<h2>II. Версии</h2>
Guitar Pro формат развивался вместе с программой. Интегрировались новые функции, которые он должен был поддержать.

Этот документ описывает структуру только Guitar Pro версии 4.06.

<a href="#Summary">К оглавлению</a>
<h2>III. Структура файла</h2>
_______________________________________________________
|	|						|
|	| Версия					|
|	|_______________________________________________|
|	|						|
|	| Табулатура					|
|	|_______________________________________________|
|Заголов|						|
|	| Текст 					|
|	|_______________________________________________|
|	|						|
|	| Другая информация о табулатуре		|
|_______|_______________________________________________|
|	|						|
|	| Меры  					|
|	|_______________________________________________|
|	|						|
|	| Дорожки					|
|	|_______________________________________________|
|	|		|		|		|
|	|		|		| нота 1 	|
|Тело	| 		| Удар 1 	|_______________|
|	|		|		|		|
|       |		|		| нота i ...	|
|       | Меры пар      |_______________|_______________|
|       | дорожек  	|               |        	|
|	|		|		| нота 1	|
|       |               | Удар i ...	|_______________|
|	|		|		|		|
|	|		|		| нота i ...	|
|_______|_______________|_______________|_______________|
|							|
| Диаграмма аккордов					|
|_______________________________________________________|

<a href="#Summary">К оглавлению</a>
<h2>IV. Заголовки</h2>
<span style="font-family: monospace;">Трудности с чтением о Guitar Pro файлов хранится в переменной
размер заголовка файла (?). Чтение файла должно быть сделано последовательно.</span>
Структура
 _
|
| <a href="#Version">Версия</a>
|_
|
| <a href="#Information_About_the_Piece">Информация о табулатуре</a>
|_
|
| <a href="#Lyrics">Текст</a>
|_
|
| <a href="#Other_information_about_the_piece">Другая информация о табулатуре</a>
|_

<a href="#Summary">К оглавлению</a>
<h3><a name="Version"></a>1. Версия</h3>
0x00000000:  <tt>30 букв строки</tt> (не считая байт, объявляющий реальную длину
<a href="#string">строки</a> , который описывался в <a href="#GENERAL">I. Основы</a>) указывают номер версии.  Только первые n
букв (n определялось ранее) рассматриваются как символы.
Возможные значения:
FICHIER GUITARE PRO v1
FICHIER GUITARE PRO v1.01
FICHIER GUITARE PRO v1.02
FICHIER GUITARE PRO v1.03
FICHIER GUITARE PRO v1.04
FICHIER GUITAR PRO v2.20
FICHIER GUITAR PRO v2.21
FICHIER GUITAR PRO v3.00
FICHIER GUITAR PRO v4.00
FICHIER GUITAR PRO v4.06
FICHIER GUITAR PRO L4.06
* Примечание переводчика: "Fichier" с французского означает "файл".  Это осталось не переведённым.
Программа ожидает строки на французском языке.
Спецификация только "FICHIER GUITAR PRO v4.06" описывается здесь.
После этого адреса (0x0000001F), данные записываются последовательно, без точного адреса.
<a href="#Summary">Summary</a>
<h3><a name="Information_About_the_Piece"></a>2. Информация об отрывке</h3>
Далее информация предоставлена в виде блоков данных, содержащих:
	- <a href="#integer">целые</a> указывающие размер информации + 1;
	- <a href="#string">Строки</a> символов, представляющих данные.
Структура требует, чтобы нулевая <a href="#string">строка</a> была записана как 01 00 00 00 00.
Информация по порядку в файла:
	- Заголовок отрывка;
	- Подзаголовок отрывка;
	- Интерпретация отрывка;
	- Альбом, из которого был взят отрывок;
	- Автор отрывка;
	- Копирайты;
	- Имя автора табулатуры;
	- Инструкции по использованию.
Следующий раздел содержит информацию об "оповещения" (обратите внимание) в поле свойства отрывка.
Он начинается <a href="#integer">целым</a> , указывающим число линий Nb_Notice указаний, тогда Nb_Notice экземпляров
структуры прежде описанной, каждая из которых содержит линии записей.
Файл будет содержать байт, определяющий атрибут "тройки чувств" отрывка.
Если "тройка чувств" активна, то значение = 1.  Если нет, то <a href="#integer">целое</a> значение = 0.
<a href="#Summary">Summary</a>
<h3><a name="Lyrics"></a>3. Текст</h3>
Следующая часть файла содержит текст, связанный с каким-то отрывком.
<strong>Внимание</strong>! Строки, описываемые здесь (и только здесь) не соответствуют
формату, описанному в "<a href="#GENERAL">I. Основах"</a>, а записываются непосредственно.
В этой секции всё начинается с <a href="#integer">целого</a>, описывающего номер трека к которому
относится текст.
Так для каждой из 5 строк, сгенерированных Guitar Pro 4, файл содержит
<a href="#integer">целое</a> представляющее число символов в <a href="#string">строке</a> с последующей <a href="#string">строкой</a>.
<a href="#Summary">К оглавлению</a>
<h3><a name="Other_information_about_the_piece"></a>4. Другая информация об отрывке.</h3>
Следующие данные:

Темп:   			<a href="#integer">целое</a>

Ключ:			        Байт
	Это значение - кодирующий ключ (подпись) в начале отрывка. Он закодирован как:
		-  0: C
		-  1: G (#)
		-  2: D (##)
		- -1: F (b) ...

Октава: 			Байт
	<tt>Стандартное значение = 0. Он становится 8, если будет сыгран на одну октаву выше</tt>.
        Эта функция пока не используется, но сделана на будущее.
Midi канал:
	Таблица миди канала.  В ней 4 порта и 16 каналов, каналы хранятся именно в таком порядке:
		port1/channel1  - port1/channel2 ... port1/channel16 - port2/channel1 ...

		Каждый элемент таблицы имеет следующий вид:
			Инструмент: 	<a href="#integer">Integer</a>
  			Громкость:   	Byte
  			Баланс: 	Byte
  			Хор:    	Byte
  			Отражение: 	Byte
  			Фазовращатель: 	Byte
  			Тремоло: 	Byte

  			blank1: 	byte =&gt; Обратная совместимость с версией 3.0
  			blank2:		byte =&gt; Обратная совместимость с версией 3.0

Число измерений:   <a href="#integer">Integer</a>
Число треков:      <a href="#integer">Integer</a>
<a href="#Summary">К оглавлению</a></pre>
<pre>
<h2>V. Тело файла</h2>
<pre>	 _________________________________
	|
	| Меры
	|_________________________________
	|
	| Дорожки
	|_________________________________
	|		|		|
	|		|		| Нота 1
	| 		| Удар 1 	|_
	|		|		|
	|		|		| Нота i ...
	| Пары мер -    |_______________|_
	|     дорожек   |               |
	|		|		| Нота 1
	|		| Удар i ...	|_
	|		|		|
	|		|		| Нота i ...
	|_______________|_______________|_

<a href="#Summary">К оглавлению</a></pre>
<h3>1. Меры</h3>
<pre>Меры написаны одна за другой, их число было указано ранее.

Первый байт - заголовка этой меры. В нем перечислены все данные, указанные в текущей мере.
    __
 7 |__| &lt;- Наличие двойного бар;
 6 |__| &lt;- Тональность меры;
 5 |__| &lt;- Наличие маркера;
 4 |__| &lt;- Количество альтернативных окончаний;
 3 |__| &lt;- Конец повторения;
 2 |__| &lt;- Начало повторения;
 1 |__| &lt;- Знаменатель в (ключе) подписи;
 0 |__| &lt;- Числитель (ключа) подписи.

Каждый из этих элементов присутствует, только если соответствующий бит 1.

Различных элементов письменной форме (если они есть) от низшего к высшему немного.

Exceptions are made for the double bar and the beginning of repeat whose sole presence
is enough, complementary data is not necessary.

Numerator of the (key) signature: 	Byte
 	Numerator of the (key) signature of the piece

Denominator of the (key) signature:	Byte
 	Denominator of the (key) signature of the piece

End of repeat:			Byte
	Number of repeats until the previous Beginning of repeat.
 	Nombre de renvoi jusqu'au début de renvoi précédent.

Number of alternate ending:	Byte
	The number of alternate ending.

Marker:
	The markers are written in two steps. First is written an <a href="#integer">integer</a> equal to
	the marker's name length + 1, and then a <a href="#string">string</a> containing the marker's
	name. Finally the marker's <a href="#color">color</a> is written.

Tonality of the measure:	Byte
	This value encodes a key (signature) change on the current piece.
	It is encoded as:
		-  0: C
		-  1: G (#)
		-  2: D (##)
		- -1: F (b) ...

<a href="#Summary">Summary</a></pre>
]]></content:encoded>
			<wfw:commentRss>http://UbuntuLinux.ru/developers/protokoly/guitar-pro-4-06-file-format-description-in-russian/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Руководство от brian d foy по отладке программ на Perl</title>
		<link>http://UbuntuLinux.ru/developers/debugging-perl-code-brians-guide/</link>
		<comments>http://UbuntuLinux.ru/developers/debugging-perl-code-brians-guide/#comments</comments>
		<pubDate>Sun, 21 Mar 2010 07:09:31 +0000</pubDate>
		<dc:creator><![CDATA[Admin]]></dc:creator>
				<category><![CDATA[Разработка под Linux]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://manlinux.org/?p=82</guid>
		<description><![CDATA[(Перевод brian’s_guide.pod) Следуйте этому руководству и берегите нервы. Моя философия отладки Я верю в три вещи: 1. Ничего личного Забудьте об авторстве кода. Вы можете считать себя художником, но даже великие художники делали много ерунды. У всех код ерундовый, то &#8230; <a href="/developers/debugging-perl-code-brians-guide/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><em>(Перевод brian’s_guide.pod)</em></p>
<p><em>Следуйте этому руководству и берегите нервы.</em></p>
<p><em> </em></p>
<p><em>Моя философия отладки</em></p>
<p>Я верю в три вещи:</p>
<p><span id="more-862"></span><span style="color: #800000;">1. Ничего личного</span></p>
<p>Забудьте об авторстве кода. Вы можете считать себя художником, но даже великие художники делали много ерунды. У всех код ерундовый, то есть мой код — ерунда, и ваш тоже. Смиритесь с этим. Если есть проблема, то первой мыслью должно быть «с моим ерундовым кодом что-то не так». Так вы не будете считать виновным Perl. Ничего личного.</p>
<p>Забудьте о том, как вы что-то делаете. Если бы ваш подход работал, вы бы это не читали. В этом нет ничего плохого, просто нужно развиваться. Все мы там будем.</p>
<p><span style="color: #800000;">2. Личная ответственность</span></p>
<p>Если есть проблема со скриптом, то это только ваша проблема. Вам нужно сделать все возможное, чтобы решить ее. Помните, что у всех остальных есть свои скрипты, то бишь свои проблемы. Сделайте домашнюю работу и попробуйте справиться сами, перед тем как дергать кого-то еще. Если вы честно перепробовали все в этом руководстве, но не решили проблему, тогда пришло время беспокоить окружающих.</p>
<p><span style="color: #800000;">3. Подход нужно менять</span></p>
<p>Исправьте все, чтобы не встретиться снова с такой же проблемой. Возможно, она в том, как вы программируете, а не в том, что. Поменяйте подход, чтобы облегчить свою жизнь. Не заставляйте Perl подстроиться под вас, потому что он этого не сделает. Подстройтесь под Perl. Это просто язык, а не образ жизни.</p>
<p><span style="color: #800000;"><br />
Мой метод</span></p>
<p>Компилируется ли ваш скрипт в строгом режиме?</p>
<p>Если вы не используете строгий режим, включите его. Perl-гуру являются гуру оттого, что используют strict, это позволяет решать другие задачи, изучать новые штуки и загружать работающие модули на CPAN.</p>
<p>Строгий режим включается прагмой strict:</p>
<p>use strict;</p>
<p>Из командной строки это можно сделать, используя опцию -M:</p>
<p>perl -Mstrict script.pl</p>
<p>После этого perl может докучать вам, но после пары недель программирования в строгом режиме ваш код станет лучше, меньше времени уйдет на отлавливание простых ошибок, а, быть может, отпадет надобность в этом руководстве.</p>
<p>Что за предупреждение?</p>
<p>Perl предупредит о многих подозрительных конструкциях. Включите предупреждения и помогите Perl помочь вам.</p>
<p>Используйте параметр -w в строке с интерпретатором:</p>
<p>#!/usr/bin/perl -w</p>
<p>Вы можете включить предупреждения из командной строки:</p>
<p>perl -w script.pl</p>
<p>Вы можете использовать лексические предупреждения со всякими интересными возможностями (подробности — в perldoc warnings).</p>
<p>use warnings;</p>
<p>Если предупреждения непонятны, посмотрите подробную версию в perldoc perldiag или используйте прагму diagnostics:</p>
<p>use diagnostics;</p>
<p>Решите сперва первую проблему!</p>
<p>Как только perl выдал вам сообщения об ошибках или предупреждения, устраните первое, а потом посмотрите, выдаются ли остальные сообщения — первая проблема и может быть их причиной.</p>
<p>Посмотрите на код перед строкой, на которую ссылается сообщение об ошибке!</p>
<p>Perl выдает предупреждения после того, как ощутит беспокойство, но не до этого. К тому времени, как perl обеспокоен, проблема уже возникла, и perl, на самом деле, находится уже после проблемы. Взгляните на пару выражений до строки под номером, указанным в предупреждении.</p>
<p>То ли здесь значение, какое вы думаете?</p>
<p>Не гадайте! На деле проверьте значение до того, как использовать его в выражении. Лучший отладчик в мире — print.</p>
<p>print STDERR “Значение — [$value]n”;</p>
<p>Я заключаю $value в скобки, чтобы видить все пробелы или переводы строк в начале или конце.</p>
<p>Если я имею дело с чем-то помимо скаляра, я использую Data::Dumper для вывода структур.</p>
<p>require Data::Dumper;</p>
<p>print STDERR “Хеш — “, Data::Dumper::Dumper( %hash ), “n”;</p>
<p>Если в значении — не то, что вы думаете, вернитесь на несколько шагов назад и попробуйте снова. Повторяйте до тех пор, пока не найдете точку, в которой значение перестает быть ожидаемым.</p>
<p>Также можете использовать встроенный отладчик perl, запустив perl с опцией -d. Детали — в perldoc perldebug.</p>
<p>perl -d script.pl</p>
<p>Еще есть другие отладчики или среды разработки вроде ptkdb (графический отладчик, основанный на Tk) или Komodo (IDE ActiveState, основанная на Mozilla).</p>
<p>Верно ли вы используете функцию?</p>
<p>Я программирую на Perl довольно давно, но все еще заглядываю в perldoc perlfunc чуть ли не каждый день. Что-то я просто не могу упомнить, а иногда по недосыпу меня покидают все чувства, и непонятно, почему sprintf() не печатает на экране.</p>
<p>Отыскать отдельную функцию с командой perldoc можно при помощи опции -f:</p>
<p>perldoc -f имя_функции</p>
<p>Если вы используете модуль, загляните в документацию, чтобы убедиться, что используете его правильно. Это делается с perldoc:</p>
<p>perldoc Имя::Модуля</p>
<p>Используете ли вы нужную специальную переменную?</p>
<p>И снова, я все время смотрю в perldoc perlvar. Нет, не так часто, с тех пор как нашел более удобной книжку «Perl Pocket Reference».</p>
<p>У вас есть нужная версия модуля?</p>
<p>Некоторые модули меняют поведение от версии к версии. У вас та версия модуля, о которой вы думаете? Вы можете узнать последнюю версию таким однострочником perl:</p>
<p>perl -MИмя::Модуля -le ‘print Имя::Модуля-&gt;VERSION’;</p>
<p>Если вы смотрите большинство документации не на локальной машине, а на <a target="_blank" rel="nofollow" href="http://www.perldoc.com/" rel="nofollow"  target="_blank">http://www.perldoc.com/</a> или <a target="_blank" rel="nofollow" href="http://search.cpan.org/" rel="nofollow"  target="_blank">http://search.cpan.org/</a>, то, вероятнее всего, вы найдете различия в версиях текстов.</p>
<p>Вы сделали небольшой тестовый пример?</p>
<p>Если вы пробуете что-то новое, или часть кода работает странно, напишите самую короткую из возможных программ, которая исполняет только тот код. Это исключит из рассмотрения большинство других вещей. Если маленькая тестовая программа делает то, что нужно, то проблема, скорее всего, не в том коде. Если программа работает неверно, то вы, возможно, нашли проблему.</p>
<p>Проверили ли вы среду?</p>
<p>Некоторые вещи зависят от переменных окружения. Вы уверены, что они верно установлены? Ваша среда совпадает с той, в которой работает программа? Помните, что CGI-программы или задачи cron могут видеть среды, отличающиеся (особенно на различных машинах) от той, что доступна из вашей интерактивной оболочки.</p>
<p>Perl хранит среду в %ENV. Если вам нужна одна из этих переменных, будьте готовы указать значение по умолчанию, если переменная не существует, даже на время тестирования.</p>
<p>Если проблема еще есть, проверьте среду:</p>
<p>require Data::Dumper;</p>
<p>print STDERR Data::Dumper::Dumper( %ENV );</p>
<p>Смотрели в Google?</p>
<p>Если у вас есть проблема, то, возможно, у кого-то была такая же. Посмотрите в Google Groups, писал ли кто нибудь об этом в comp.lang.perl.misc. Разница между людьми, задающими вопросы в USENET и отвечающими на них — в умении эффективно искать по Google Groups.</p>
<p>Профайлер использовали?</p>
<p>Если хотите прокрутить медленные участки программы, использовали ли вы профайлер? Пусть тяжелую работу за вас сделает Devel::SmallProf. Он считает количество исполнения строки кода и продолжительность процесса, после чего показывает красивый отчет.</p>
<p>Какой тест не работает?</p>
<p>Если у вас есть набор тестов, то какой тест не срабатывает? Вы должны быть способны очень быстро найти ошибку, так как каждый тест исполняет лишь малую часть кода.</p>
<p>Если набора тестов нет, почему бы его не сделать? Я не прошу вас писать пару тестов, если скрипт по-настоящему маленький или одноразовый. Но все другое реально выиграет от нескольких тестовых скриптов. Test::Harness делает это столь простым, что у вас нет оправданий не использовать тесты. Если нет времени, возможно, вы тратите слишком много на отладку скриптов без тестов. MakeMaker, в конце-концов, нужен не только для модулей.</p>
<p>Думаете вслух?</p>
<p>Объсните проблему вслух. По-настоящему проговорите слова.</p>
<p>Пару лет я имел счастье работать с очень хорошим программистом, который мог справиться практически со всем. Когда я застревал на чем-то, я шел к его столу и начинал объяснять проблему. Обычно не проходило и трех предложений, как я прерывался: «забудь, я понял» (но и он почти всегда находил решение).</p>
<p>Так как вам это, видимо, придется делать очень часто, советую выбрать в качестве Perl-терапевта нечто вроде плюшевой игрушки и не досаждать коллегам. У меня на столе сидит маленький мишка, и я объясняю проблемы ему. Моя подружка даже уже не обращает внимания, когда я разговариваю сам с собой.</p>
<p>Выглядит ли проблема иначе на бумаге?</p>
<p>Вы глазели на экран компьютера, и, быть может, на другом носителе вещи будут выглядеть иначе. Попробуйте посмотреть на распечатку программы.</p>
<p>Смотрели сегодня ТВ-шоу?</p>
<p>Серьезно. Сделайте перерыв. Перестаньте на время думать о проблеме и дайте отдых мозгам. Вернитесь к проблеме позже, и решение может оказаться очевидным.</p>
<p>Вы уменьшили свое самомнение?</p>
<p>Если вы еще не покончили, проблема может быть психологической. Вы можете быть эмоционально привязанными к отдельной части кода, поэтому не менять ее. Вы также можете думать, что все неверно, кроме вас. Тогда вы не считаетесь всерьез с самым вероятным источником ошибок — самим собой. Ничего не упускайте. Проверьте все.</p>
]]></content:encoded>
			<wfw:commentRss>http://UbuntuLinux.ru/developers/debugging-perl-code-brians-guide/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Guitar Pro 4.06 File Format Description</title>
		<link>http://UbuntuLinux.ru/developers/protokoly/guitar-pro-4-06-file-format-description/</link>
		<comments>http://UbuntuLinux.ru/developers/protokoly/guitar-pro-4-06-file-format-description/#comments</comments>
		<pubDate>Sun, 21 Mar 2010 05:24:33 +0000</pubDate>
		<dc:creator><![CDATA[Admin]]></dc:creator>
				<category><![CDATA[Протоколы]]></category>
		<category><![CDATA[gp4]]></category>
		<category><![CDATA[Guitar Pro]]></category>

		<guid isPermaLink="false">http://manlinux.org/?p=78</guid>
		<description><![CDATA[GUITAR PRO FILE FORMAT v4.06 Version: 1.0RC1 English Author: Laurent Vromman Translator: Avery Ceo, Matthieu Wipliez Conversion to HTML: Mauricio Gracia Gutiérrez (corrections, added information) Property Of: Arobas-Music Summary I. GENERAL II. VERSIONS III. FILE STRUCTURE IV. HEADERS 1. Version &#8230; <a href="/developers/protokoly/guitar-pro-4-06-file-format-description/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><span id="more-860"></span><br />
<table border="0" cellspacing="2" cellpadding="2" summary="GP4 format description">
<tbody>
<tr>
<td>
<pre>GUITAR PRO FILE FORMAT v4.06

Version:   1.0RC1 English
Author:    Laurent Vromman
Translator: Avery Ceo, Matthieu Wipliez
Conversion to HTML: Mauricio Gracia Gutiérrez (corrections, added information)
Property Of: Arobas-Music</pre>
<hr />
<h2><a name="Summary"></a>Summary</h2>
<pre>
	I.   <a href="#GENERAL">GENERAL</a>
	II.  <a href="#VERSIONS">VERSIONS</a>
	III. <a href="#File_Structure">FILE STRUCTURE</a>
	IV.  <a href="#HEADERS">HEADERS</a>
		 1. <a href="#Version">Version</a>
		 2. <a href="#Information_About_the_Piece">Information about the piece</a>
		 3. <a href="#Lyrics">Lyrics</a>
		 4. <a href="#Other_information_about_the_piece">Other information about the piece</a>
	V.   <a href="#FILE_BODY">FILE BODY</a>
		 1. <a href="#Measures">Measures</a>
		 2. <a href="#Tracks">Tracks</a>
		 3. <a href="#Measures-Tracks_pairs">Measure-Track pairs</a>
		 4. <a href="#A_beat">Beats</a>
		 5. <a href="#Chords_diagrams">Chord diagrams</a>
 		 6. <a href="#Effects_on_beats">Effects on the beats</a>
 		 7. <a href="#Mix_table_change_event">Mix table change event</a>
 		 8. <a href="#Note">Notes</a>
 		 9. <a href="#Effects_on_the_notes">Effects on the notes</a>
 		 	a. <a href="#Effects_on_the_notes_2">Effects on the notes</a>
 			b. <a href="#Grace_notes">Grace notes</a>
 		10. <a href="#Bends">Bends</a>
 	VI.  <a href="#CHORDS_DIAGRAMS2">CHORDS DIAGRAMS</a></pre>
</td>
</tr>
<tr>
<td>
<h2><a name="GENERAL"></a>I. GENERAL</h2>
<p><a name="integer"></a>Values of type "integer" are stored in 4 bytes.<br />
<a name="short_int"></a>Values of type "short int" are stored in 2 bytes.<br />
<a name="byte"></a>Values of type "byte" are stored in 1 byte.</p>
<p>Values of type "integer" and "byte" presented in this document<br />
are written from left to right of the the LSB (least significant byte)<br />
to the MSB (most significant byte).</p>
<p><a name="color"></a>The colors are stored in 4 bytes in the following way, the data is written from left to right of<br />
the LSB (least significant byte) to the MSB (most significant byte):</p>
<pre>   __
3 |__| &lt;- White byte, it always evaluates to 0x00;
2 |__| &lt;- Blue;
1 |__| &lt;- Green;
0 |__| &lt;- Red.</pre>
<p><a name="string"></a>When this document uses the expression "character string," it means a couple of<br />
a first byte encoding the number 'n' of characters in the string (consequently limited to 255 characters),<br />
followed by the 'n' characters themselves.</p>
<p>The musical notes are stored as <a href="#integer">integers</a>. The value of the C(0) is 0, and each incrementation of<br />
the variable represents a half tone:</p>
<pre>- C#(0) = 1;
- C (1) = 12;
- E (2) = 28 ...</pre>
<pre><a href="#Summary">Summary</a></pre>
<hr />
<h2><a name="VERSIONS"></a>II. VERSIONS</h2>
<p>The Guitar Pro format has evolved with the program to integrate the new functionalities that it provides.</p>
<p>This document describes the structure of the Guitar Pro version 4.06 files only.</p>
<pre><a href="#Summary">Summary</a></pre>
<hr />
<h2><a name="File_Structure"></a>III. File Structure</h2>
<pre>
	 _______________________________________________________
	|	|						|
	|	| Version					|
	|	|_______________________________________________|
	|	|						|
	|	| Tablature					|
	|	|_______________________________________________|
	|Headers|						|
	|	| Lyrics					|
	|	|_______________________________________________|
	|	|						|
	|	| Other Tablature Information			|
	|_______|_______________________________________________|
File	|	|						|
	|	| Measures					|
	|	|_______________________________________________|
	|	|						|
	|	| Tracks					|
	|	|_______________________________________________|
	|	|		|		|		|
	|	|		|		| Note 1 	|
	|Body	| 		| Beat 1 	|_______________|
	|	|		|		|		|
	|       |		|		| Note i ...	|
	|       | Measure-Track |_______________|_______________|
	|       | Pairs  	|               |        	|
	|	|		|		| Note 1	|
	|       |               | Beat i ...	|_______________|
	|	|		|		|		|
	|	|		|		| Note i ...	|
	|_______|_______________|_______________|_______________|
	|							|
	| Chord Diagrams					|
	|_______________________________________________________|

<a href="#Summary">Summary</a></pre>
<hr /></td>
</tr>
<tr>
<td>
<h2><a name="HEADERS"></a>IV. HEADERS</h2>
<pre>
<tt>The difficulty in reading about the Guitar Pro files resides in the variable
size of the file's header.  Reading the file must therefore be done sequentially.</tt></pre>
<pre>	Structure
   	 _
	|
	| <a href="#Version">Version</a>
	|_
	|
	| <a href="#Information_About_the_Piece">Tablature Information</a>
	|_
	|
	| <a href="#Lyrics">Lyrics</a>
	|_
	|
	| <a href="#Other_information_about_the_piece">Other Tablature Information</a>
	|_

<a href="#Summary">Summary</a></pre>
<hr />
<h3><a name="Version"></a>1. Version</h3>
<pre>
0x00000000:  <tt>30 character string</tt> (not counting the byte announcing the real length of
the <a href="#string">string</a> as explained in <a href="#GENERAL">I. GENERAL</a>) representing the version number.  Only the first n
characters (n being given by the value described previously) characters are considered.</pre>
<pre>The different values possible at this time are:
	FICHIER GUITARE PRO v1
	FICHIER GUITARE PRO v1.01
	FICHIER GUITARE PRO v1.02
	FICHIER GUITARE PRO v1.03
    	FICHIER GUITARE PRO v1.04
    	FICHIER GUITAR PRO v2.20
    	FICHIER GUITAR PRO v2.21
    	FICHIER GUITAR PRO v3.00
    	FICHIER GUITAR PRO v4.00
    	FICHIER GUITAR PRO v4.06
    	FICHIER GUITAR PRO L4.06</pre>
<pre>*Translator's Note: "Fichier" is French for "File".  It is left untranslated above, as
the program expects the <a href="#string">string</a> in French.</pre>
<pre>Only the specifications relating to version "FICHIER GUITAR PRO v4.06" are described here.</pre>
<pre>After this point (0x0000001F), the data is written sequentially without a precise address.</pre>
<pre><a href="#Summary">Summary</a></pre>
<hr />
<h3><a name="Information_About_the_Piece"></a>2. Information About the Piece</h3>
<pre>
The follollowing information is presented in the form of a block of data containing:
	- an <a href="#integer">integer</a> representing the size of the stored information + 1;
	- the <a href="#string">string</a> of characters representing the data</pre>
<pre>This structure requires that a null <a href="#string">string</a> be written 01 00 00 00 00 in the file.</pre>
<pre>The information concerned is, in order of reading within the file:
	- The title of the piece;
	- The subtitle of the piece;
	- The interpret of the piece;
	- The album from which the piece was taken;
	- The author of the piece;
	- The copyright;
	- The name of the author of the tablature;
	- An 'instructional' line about the tablature.</pre>
<pre>The following section contains information regarding the 'notice' (note) field in the piece's properties.
It begins with an <a href="#integer">integer</a> containing the number of lines of Nb_Notice notes, then Nb_Notice instances of
the structure previously described, each containing lines of notes.</pre>
<pre>The file then contains a byte determining the 'TripletFeel' attribute of the piece.
If TripletFeel is activated, the value is 1.  If not, the <a href="#integer">integer</a> value is 0.</pre>
<pre><a href="#Summary">Summary</a></pre>
<hr />
<h3><a name="Lyrics"></a>3. Lyrics</h3>
<pre>
The next section of the file contains the lyrics associated with the piece.</pre>
<pre>WARNING: The strings presented in this section and in this section only do not conform to the
format presented in "<a href="#GENERAL">I. General"</a>, but are written directly.</pre>
<pre>The lyrics section begins with an <a href="#integer">integer</a> giving the number of the track with which the
lyrics are associated.</pre>
<pre>Then, for each of the 5 lines of lyrics generated by Guitar Pro 4, the file contains an
<a href="#integer">integer</a> representing the number of characters in the <a href="#string">string</a> followed by the character <a href="#string">string</a> itself.</pre>
<pre><a href="#Summary">Summary</a></pre>
<hr />
<h3><a name="Other_information_about_the_piece"></a>4. Other information about the piece</h3>
<pre>
The next data is:

The tempo:			<a href="#integer">Integer</a>

The key:			Byte
	This value encodes the key (signature) at the beginning of the piece.  It is encoded as:
		-  0: C
		-  1: G (#)
		-  2: D (##)
		- -1: F (b) ...

The Octave:			Byte
	<tt>The standard value is 0. It becomes 8 if the sheet is to be played one octave higher (8va)</tt>.

        This functionality is not yet used, but is presented as a preview of a revision of the GP4 format.

Midi Channels:
	Table of midi channels.  There are 4 ports and 16 channels, the channels are stored in this order:
		port1/channel1  - port1/channel2 ... port1/channel16 - port2/channel1 ...

		Each element of the table has the following form:
			Instrument: 	<a href="#integer">Integer</a>
  			Volume: 	Byte
  			Balance: 	Byte
  			Chorus: 	Byte
  			Reverb: 	Byte
  			Phaser: 	Byte
  			Tremolo: 	Byte

  			blank1: 	byte =&gt; Backward compatibility with version 3.0
  			blank2:		byte =&gt; Backward compatibility with version 3.0

Number of Measures:   <a href="#integer">Integer</a>
Number of Tracks:    <a href="#integer">Integer</a></pre>
<pre><a href="#Summary">Summary</a></pre>
<hr /></td>
</tr>
<tr>
<td valign="top">
<h2><a name="FILE_BODY"></a>V. FILE BODY</h2>
<pre>	 _________________________________
	|
	| Mesures
	|_________________________________
	|
	| Tracks
	|_________________________________
	|		|		|
	|		|		| Note 1
	| 		| Beat 1 	|_
	|		|		|
	|		|		| Note i ...
	| Measure-track |_______________|_
	|     Pairs     |               |
	|		|		| Note 1
	|		| Beat i ...	|_
	|		|		|
	|		|		| Note i ...
	|_______________|_______________|_



<a href="#Summary">Summary</a></pre>
<hr />
<h3><a name="Measures"></a>1. Measures</h3>
<pre>
The measures are written one after another, their number having been specified previously.

The first byte is the measure's header.  It lists the data given in the current measure.
    __
 7 |__| &lt;- Presence of a double bar;
 6 |__| &lt;- Tonality of the measure;
 5 |__| &lt;- Presence of a marker;
 4 |__| &lt;- Number of alternate ending;
 3 |__| &lt;- End of repeat;
 2 |__| &lt;- Beginning of repeat;
 1 |__| &lt;- Denominator of the (key) signature;
 0 |__| &lt;- Numerator of the (key) signature.

Each of these elements is present only if the corresponding bit is a 1.

The different elements are written (if they are present) from lowest to highest bit.

Exceptions are made for the double bar and the beginning of repeat whose sole presence
is enough, complementary data is not necessary.

Numerator of the (key) signature: 	Byte
 	Numerator of the (key) signature of the piece

Denominator of the (key) signature:	Byte
 	Denominator of the (key) signature of the piece

End of repeat:			Byte
	Number of repeats until the previous Beginning of repeat.
 	Nombre de renvoi jusqu'au début de renvoi précédent.

Number of alternate ending:	Byte
	The number of alternate ending.

Marker:
	The markers are written in two steps. First is written an <a href="#integer">integer</a> equal to
	the marker's name length + 1, and then a <a href="#string">string</a> containing the marker's
	name. Finally the marker's <a href="#color">color</a> is written.

Tonality of the measure:	Byte
	This value encodes a key (signature) change on the current piece.
	It is encoded as:
		-  0: C
		-  1: G (#)
		-  2: D (##)
		- -1: F (b) ...

<a href="#Summary">Summary</a></pre>
<hr />
<h3><a name="Tracks"></a>2. Tracks</h3>
<pre>
The tracks are written one after another, their number having been specified previously.

The first byte is the track's header.  It precises the track's attributes:
    __
 7 |__| &lt;- Blank bit;
 6 |__| &lt;- Blank bit;
 5 |__| &lt;- Blank bit;
 4 |__| &lt;- Blank bit;
 3 |__| &lt;- Blank bit;
 2 |__| &lt;- Banjo track;
 1 |__| &lt;- 12 stringed guitar track;
 0 |__| &lt;- Drums track.

Name:				String
	A 40 characters long <a href="#string">string</a> containing the track's name.

Number of strings:		<a href="#integer">Integer</a>
	An <a href="#integer">integer</a> equal to the number of strings of the track.

Tuning of the strings:		Table of <a href="#integer">integers</a>
	The tuning of the strings is stored as a 7-<a href="#integer">integers</a> table, the "Number of
	strings" first <a href="#integer">integers</a> being really used. The strings are stored from
	the highest to the lowest.

Port:				<a href="#integer">Integer</a>
	The number of the MIDI port used.

Channel:			<a href="#integer">Integer</a>
	The number of the MIDI channel used. The channel 10 is the drums channel.

ChannelE:			<a href="#integer">Integer</a>
	The number of the MIDI channel used for effects.

Number of frets:		<a href="#integer">Integer</a>
	The number of frets of the instrument.

Height of the capo:		<a href="#integer">Integer</a>
	The number of the fret on which a capo is present. If no capo is used, the
	value is 0x00000000.

Track's color:			<a href="#color">Color
</a>	The track's displayed color in Guitar Pro.

<a href="#Summary">Summary</a></pre>
<hr />
<h3><a name="Measures-Tracks_pairs"></a>3. Measures-Tracks pairs</h3>
<pre>
The list of <a href="#A_beat">beats</a> per track and per measure is then written to the file in the
following order:

	Measure 1/Track 1
	Measure 1/Track 2
	...
	Measure 1/Track M
	Measure 2/Track 1
	...
	Measure 2/Track M
	...
	Measure N/Track 1
	Measure N/Track 2
	...
	Measure N/Track M

A measure-track pair is written in two steps. We first write the number of beats
in the current pair:

Number of beats:		<a href="#integer">Integer</a>
	<a href="#integer">Integer</a> indicating the number of beats the measure-track pair contains.

After what we directly write the beat details (which are described in the <a href="#A_beat">next section</a>).

<a href="#Summary">Summary</a></pre>
<hr />
<h3><a name="A_beat"></a>4. A beat</h3>
<pre>
The first byte is the beat header. It lists the data present in the current beat:
    __
 7 |__| &lt;- Blank bit;
 6 |__| &lt;- Status: True if the beat is empty of if it is a rest;
 5 |__| &lt;- The beat is a n-tuplet;
 4 |__| &lt;- Presence of a mix table change event;
 3 |__| &lt;- Presence of effects;
 2 |__| &lt;- Presence of a text;
 1 |__| &lt;- Presence of a chord diagram;
 0 |__| &lt;- Dotted notes.


Status:				Byte
	If the bit 6 is true, we start by writing the beat status. The value is
	0x00 if the beat is empty and 0x02 if it is a rest.

Beat duration:			Byte
	The basic beat duration is a eighth note, which is equivalent to a
	time duration of 1. We thus obtain the following relations:
 		* -2:	Whole note;
 		* -1:	Half note;
 		*  0:	Quarter note;
 		*  1:	Eighth note;
 		*  2:	Sixteenth note;
 	 	*  3:	Thirty-second note;
 	 	* ...

N-tuplet:			<a href="#integer">Integer</a>
	If the bit 5 of the header byte is true, this <a href="#integer">integer</a> corresponds to the
	'n' in 'n-tuplet': 3, 5, 6, 7, 9, 10, 11, 12 and 13.

Chord diagram:
	If the presence of a chord diagram is indicated by the bit 1 of the
	header, it is then written here. The detail of this operation is specified
	in paragraph <a href="#Chords_diagrams">V.5 Chords diagrams</a>.

Text:
	If the presence of a text is indicated by the bit 2 of the header, it is
	written here. It behaves like most of the previous strings. We
	first find an <a href="#integer">integer</a> coding the text length + 1, followed by the <a href="#string">string</a>
	containing the text (at the format described in <a href="#GENERAL">I. GENERAL</a>).

Effect on beats:
	If the presence of an effect is indicated by the bit 3 of the header, it
	is written at this place. The detail of this operation is specified in the
	paragraph <a href="#Effects_on_beats">V.6 Effects on beats</a>. Effects on beats include tremolo bars,
	bends...

Mix table change event:
	If the presence of an event linked to the mix table is indicated by the
	bit 4 of the header, it is written here. The detail of this operaion is
	specified in the paragraph <a href="#7._Mix_table_change_event">V.7 Mix table change event</a>.

Note:
	The note itself is written here. The detail of this operation is specified
	in the paragraph <a href="#8._Note">V.8 Note</a>.

<a href="#Summary">Summary</a></pre>
<hr />
<h3><a name="5._Chords_diagrams"></a><a name="Chords_diagrams"></a>5. Chords diagrams</h3>
<pre>
Header:				Byte
	This value is 0x01, indicating a Guitar Pro 4 format chord.

Sharp: 				Byte
	Determines if the chord is displayed sharp or flat.

Blank1,
Blank2,
Blank3: 			Bytes
	Blank bytes needed for ascendant compatibility with versions 3 of the software.

Root:				Byte
 	* -1 for the customized chords
 	*  0: C
 	*  1: C#...

Major/minor:			Byte
	Determines the chord type as followed:
		-  0: M
		-  1: 7
		-  2: 7M
		-  3: 6
		-  4: m
		-  5: m7
		-  6: m7M
		-  7: m6
		-  8: sus2
		-  9: sus4
		- 10: 7sus2
		- 11: 7sus4
		- 12: dim
		- 13: aug
		- 14: 5

Nine, Eleven of Thirteen:	Byte
	Determines if the chord goes until the ninth, the eleventh, or the thirteenth.

Bass: 				<a href="#integer">Integer</a>
	Lowest note of the chord. It gives the chord inversions.

Diminished/Augmented		<a href="#integer">Integer</a>
	Tonality linked with 9/11/13:
		0: perfect ("juste")
		1: augmented
		2: diminished

add: 				Byte
	Allows to determine if a 'add' (added note) is present in the chord.

Name: 				String
	20 characters long <a href="#string">string</a> containing the chord name.


Blank4,
Blank5: 			Bytes
	Blank bytes needed for ascendant compatibility with versions 3 of the software.

Fifth: 				Byte
	Tonality of the fifth:
		0: perfect ("juste")
		1: augmented
		2: diminished

Ninth: 				Byte
	Tonality of the ninth:
		0: perfect ("juste")
		1: augmented
		2: diminished
	This tonality is valid only if the value "Nine, Eleven or Thirteen" is 11 or 13.

Eleventh: 			Byte
	Tonality of the eleventh:
		0: perfect ("juste")
		1: augmented
		2: diminished
	This tonality is valid only if the value "Nine, Eleven or Thirteen" is 13.

Base fret:			<a href="#integer">Integer</a>
	Shows the fret from which the chord is displayed.

Frets: 				List of 7 <a href="#integer">integers</a>.
	Corresponds to the fret number played on each <a href="#string">string</a>, from the highest to the lowest.
	-1 means a <a href="#string">string</a> unplayed.
	0 means a <a href="#string">string</a> played "blank" (ie no fret).

Number of barres: 		Byte
	Indicates the number of barres there are in the chord. A chord can contain up to 5 barres.

Fret of the barre:		List of 5 Bytes
	Indicates the fret number of each possible barre.

Barre start:			List of 5 Bytes
	Indicates the first <a href="#string">string</a> of the barre, 1 being the highest.
        The list order matches the chord different barres frets list order.

Barre end: 			List of 5 Bytes
	Indicates the first <a href="#string">string</a> of the barre, 1 being the lowest.
        The list order matches the chord different barres frets list order.

Omission1,
Omission3,
Omission5,
Omission7,
Omission9,
Omission11,
Omission13:  			Bytes
	Gives the notes there are in the chord.
        If the value is 0x00, the note is not in the chord, and if the value is
        0x01, the note is in the chord. 9, 11 or 13 can only be present
        for a "Nine, Eleven or Thirteen" big enough.

Blank6: 			Byte
	Blank byte needed for ascendant compatibility with versions 3 of the software.

Fingering:			List of 7 Bytes
	Describes the fingering used to play the chord.
        Below is given the fingering from the highest <a href="#string">string</a> to the lowest:
		-2: unknown;
		-1: X or 0 (no finger);
		 0: thumb;
		 1: index;
		 2: middle finger;
		 3: annular;
		 4: little finger.

ShowDiagFingering:		Byte
	If it is 0x01, the chord fingering is displayed.
	If it is 0x00, the chord fingering is masked.

<a href="#Summary">Summary</a></pre>
<hr />
<h3><a name="Effects_on_beats"></a>6. Effects on beats</h3>
<pre>
The first byte is the header of effects linked to beats. It gives information about existing effects:
    __
 7 |__| &lt;- Blank bit;
 6 |__| &lt;- Stroke effect;
 5 |__| &lt;- Tapping, popping or slapping effect;
 4 |__| &lt;- unused bit -&gt; remainings of version 3;
 3 |__| &lt;- unused bit -&gt; remainings of version 3;
 2 |__| &lt;- unused bit -&gt; remainings of version 3;
 1 |__| &lt;- unused bit -&gt; remainings of version 3;
 0 |__| &lt;- unused bit -&gt; remainings of version 3.

The 2nd byte is linked with effects new to the version 4 of the software.
    __
 7 |__| &lt;- Blank bit;
 6 |__| &lt;- Blank bit;
 5 |__| &lt;- Blank bit;
 4 |__| &lt;- Blank bit;
 3 |__| &lt;- Blank bit;
 2 |__| &lt;- Tremolo Bar;
 1 |__| &lt;- Pickstroke;
 0 |__| &lt;- Rasguedo.

The effects, if any, are then written in the following order:

Tapping/Popping/Slapping:	Byte
	The presence of this effect is set by the bit 5 of the first header byte.
        It is written as:
 		0: None
 		1: Tapping
 		2: Slapping
 		3: Popping (bass guitar)

Tremolo Bar:			<a href="#10._Bends">Bend
</a>	The presence of this effect is set by the bit 2 of the second header byte.
 	The tremolo bar is saved as a BEND, as described in the paragraph <a href="#10._Bends">V.10 Bends</a>.

UpStroke:			Byte
	The presence of this effect is set by the bit 6 of the first header byte.
        It can take different values depending on the stroke speed:
 		0: none;
 		1: hundred twenty eighth note;
 		2: sixty-fourth note;
 		3: thirty-second note;
 		4: sixteenth note;
 		5: eighth note;
 		6: quarter note.

DownStroke:			Byte
	The presence of this effect is set by the bit 6 of the first header byte.
        It can take different values depending on the stroke speed:
 		0: none;
 		1: hundred twenty eighth note;
 		2: sixty-fourth note;
 		3: thirty-second note;
 		4: sixteenth note;
 		5: eighth note;
 		6: quarter note.

Rasguedo:
	The rasguedo is set if the bit 0 of the second header byte is set. It is
        a complement to the strokes, so it does not need any additional data.


Pickstroke:			Byte
	The presence of this effect is set by the bit 1 of the second header byte.
        It can take different values:
 		0: none;
 		1: going up;
 		2: going down.


<a href="#Summary">Summary</a></pre>
<hr />
<h3><a name="7._Mix_table_change_event"></a><a name="Mix_table_change_event"></a>7. Mix table change event</h3>
<pre>
Instrument:   			Byte
	Gives the number of the new instrument. The value is -1 if no instrument change occurs.

Volume:       			Byte
	Gives the new volume value. The value is -1 if no volume change occurs.

Pan:       			Byte
	Gives the new pan value. The value is -1 if no pan change occurs.

Chorus:       			Byte
	Gives the new chorus value. The value is -1 if no chorus change occurs.

Reverb:       			Byte
	Gives the new reverb value. The value is -1 if no reverb change occurs.

Phaser:       			Byte
	Gives the new phaser value. The value is -1 if no phaser change occurs.

Tremolo:      			Byte
	Gives the new tremolo value. The value is -1 if no tremolo change occurs.

Tempo:        			<a href="#integer">Integer</a>
	Gives the new tempo value. The value is -1 if no tempo change occurs.

Volume change duration:		Byte
	Gives the volume change duration in beats.

Pan change duration: 		Byte
	Gives the pan change duration in beats.

Chorus change duration:		Byte
	Gives the chorus change duration in beats.

Reverb change duration:		Byte
	Gives the reverb change duration in beats.

Phaser change duration:		Byte
	Gives the phaser change duration in beats.

Tremolo change duration:	Byte
	Gives the tremolo change duration in beats.

Tempo change duration:		Byte
	Gives the tempo change duration in beats.

The next byte precises if the changes apply only to the current track (if the
matching bit is 0), or to every track (if it is 1).
    __
 7 |__| &lt;- Blank bit;
 6 |__| &lt;- Blank bit;
 5 |__| &lt;- Tremolo;
 4 |__| &lt;- Phaser;
 3 |__| &lt;- Reverb;
 2 |__| &lt;- Chorus;
 1 |__| &lt;- Pan;
 0 |__| &lt;- Volume.

<a href="#Summary">Summary</a></pre>
<hr />
<h3><a name="8._Note"></a><a name="Note"></a>8. Note</h3>
<pre>
The first byte is the note header. It lists the information about the different
parameters linked to the note:
    __
 7 |__| &lt;- Right hand or left hand fingering;
 6 |__| &lt;- Accentuated note;
 5 |__| &lt;- Note type (rest, empty note, normal note);
 4 |__| &lt;- Note dynamic;
 3 |__| &lt;- Presence of effects linked to the note;
 2 |__| &lt;- Ghost note;
 1 |__| &lt;- Dotted note;
 0 |__| &lt;- Time-independent duration.

Note type:			<a href="#short_int">Short Int</a>
 	If the bit 5 is true, we start by writing the note type. The value is:
 		0x0100 if the note is normal;
 		0x0200 if the note is a ghost note;
 		0x0300 if the note is a tie note.

Note duration:
	If the bit 0 is true, we write the 2 following information linked to the
        note duration.

	Time duration:		Byte
        	The basic time duration is the quarter note, which is equivalent
                to a time duration of 1. Therefore, we obtain the relations:
 			* -2:	Whole Note;
 			* -1:	Half note;
 			*  0:	Quarter note;
 			*  1:	Eighth note;
 			*  2:	Sixteenth note;
 	 		*  3:	Thirty-second note;
 	 		* ...

 	N-tuplet:		Byte
        	This int matches the N in "N-tuplet" (ie 3, 5, 6, 7, 9, 10, 11, 12, 13).

Note dynamic:			Byte
	If the bit 4 of the header byte is true, we write here the note strength
        with the following rule:
		- 1: ppp
		- 2: pp
		- 3: p
		- 4: mp
		- 5: mf
		- 7: f
		- 8: ff
		- 9: fff
	If the bit 4 is false, we then consider that the note is forte (value 6).

Fret number:			Byte
	If the bit 5 is true, we write here the number of the fret on which the note
        is applied.

Fingering:			List of 2 bytes
	If the bit 7 is true, we write here successively the fingerings left hand,
        then right hand, each of them being written on one byte. The fingering
        is coded this way:
		-1: nothing;
		 0: thumb;
		 1: index;
		 2: middle finger;
		 3: annular;
		 4: little finger.

Effects on the note:
	If the presence of an effect is indicated by the bit 3 of the header, it
        is saved at this place. The details of this operation is specified in the
        next paragraph. Those include for example vibratos, palm muting,
        slides, harmonices...

<a href="#Summary">Summary</a></pre>
<hr />
<h3><a name="Effects_on_the_notes"></a>9. Effects on the notes</h3>
<pre><a name="Effects_on_the_notes_2"></a>a. Effects on the notes</pre>
<pre>
The effects presence for the current note is set by the 2 header bytes.

First byte:
    __
 7 |__| &lt;- Blank bit;
 6 |__| &lt;- Blank bit;
 5 |__| &lt;- Blank bit;
 4 |__| &lt;- Grace note presence;
 3 |__| &lt;- Let ring;
 2 |__| &lt;- Presence of a slide from the current note (version 3);
 1 |__| &lt;- Presence of a hammer-on or a pull-off from the current note;
 0 |__| &lt;- Presence of a bend.

Second byte:
    __
 7 |__| &lt;- Blank bit;
 6 |__| &lt;- Left hand vibrato;
 5 |__| &lt;- Trill;
 4 |__| &lt;- Harmonic note;
 3 |__| &lt;- Presence of a slide from the current note;
 2 |__| &lt;- Tremolo picking;
 1 |__| &lt;- Palm Mute;
 0 |__| &lt;- Note played staccato.

Bend:
	If the bit 0 of the first header byte is true, we write here the bend as
        described in section <a href="#Bends">V.10. Bends</a>.

Grace Note:
	If the bit 4 of the first header byte is true, we write here the data
        relative to the Grace Note, as described in section <a href="#b._Grace_notes">V.9.b Grace Notes</a>.

Tremolo Picking:		Byte
	If the bit 2 of the second header byte is true, the information linked to
        tremolo picking are saved here. It is encoded like this:
		- 1: eighth note;
		- 2: sixteenth note;
		- 3: thirty-second note.

Slide:				Byte
	If the bit 3 of the second header byte is true, the information linked to
        the slide is stored here and is coded like this:
		* -2: slide into from above
		* -1: slide into from below
		*  0: no slide
		*  1: shift slide
		*  2: legato slide
		*  3: slide out of downwards
		*  4: slide out of upwards

Harmonics:			Byte
	If the bit 4 of the second header byte is true, the information linked to
        the harmonics is stored here and is coded like this:
		- 0:  None
		- 1:  Natural
		- 15: Artificial+5
		- 17: Artificial+7
		- 22: Artificial+12
		- 3:  Tapped
		- 4:  Pitch
		- 5:  Semi

Trill:
	If the bit 5 of the second header byte is true, the information linked to
        the Trill effect is stored here. It is written in two steps:
		Fret:		Byte
			The fret the trill is made with.

		Period:		Byte
                	The period between each note. The value is encoded as:
				- 0: Quarter note;
				- 1: Eighth note;
				- 2: Sixteenth note.

The following effects are present if the bit of the header is true:
	- Let ring
	- Presence of a hammer-on or a pull-off from the current note
	- Left hand vibrato
	- Palm Mute
	- Note played staccato.

<a href="#Summary">Summary</a></pre>
<hr />
<h4><a name="b._Grace_notes"></a><a name="Grace_notes"></a>b. Grace notes</h4>
<pre>
The grace notes are stored in the file with 4 variables, written in the following
order.

Fret:				Byte
	The fret number the grace note is made from.

Dynamic: 			Byte
	The grace note dynamic is coded like this:
		- 1: ppp
		- 2: pp
		- 3: p
		- 4: mp
		- 5: mf
		- 6: f
		- 7: ff
		- 8: fff
	The default value is 6.

Transition:			Byte
	This variable determines the transition type used to make the grace note:
		- 0: None
		- 1: Slide
		- 2: Bend
		- 3: Hammer

Duration:			Byte
	Determines the grace note duration, coded this way:
		- 3: Sixteenth note.
		- 2: Twenty-fourth note.
		- 1: Thirty-second note.


<a href="#Summary">Summary</a></pre>
<hr />
<h4><a name="10._Bends"></a><a name="Bends"></a>10. Bends</h4>
<pre>
Type:				Byte
	Gives the bend type. Different types are allowed and are context-dependent (tremolo bar or bend).
	The model list is:
		Common:
			- 0: None

		Bend specific:
			- 1: Bend
			- 2: Bend and Release
			- 3: Bend and Release and Bend
			- 4: Prebend
			- 5: Prebend and Release

		Tremolo bar specific:
			- 6: Dip
			- 7: Dive
			- 8: Release (up)
			- 9: Inverted dip
			-10: Return
			-11: Release (down)

Value:				<a href="#integer">Integer</a>
	Bend height. It is 100 per tone and goes by quarter tone.
		* Normal position:	0;
		* Quarter tone: 	25;
		* Half tone:		50;
		* Three-quarters tone:	75;
		* Whole tone:		100;
		... until
		* Three tones:		300.


Number of points:		<a href="#integer">Integer</a>
	Number of points used to display the bend. Is followed by the list of points.

List of points:
	Each point is written like this:
		Absolute time position		<a href="#integer">Integer</a>
			Gives the point position from the previous point. This value goes between 0 and 60
                        and represents sixties of the note duration.

		Vertical position		<a href="#integer">Integer</a>
                	It is 100 per tone and goes by quarter tone.
			* Normal position:	0;
			* Quarter tone: 	25;
			* Half tone:		50;
			* Three-quarters tone:	75;
			* Whole tone:		100;
			... until
			* Three tones:		300.

		Vibrato				Byte
                	Determines how to play the section, with different vibrato types:
				- 0: none
				- 1: fast
				- 2: average
				- 3: slow

<a href="#Summary">Summary</a></pre>
<hr /></td>
</tr>
<tr>
<td valign="top">
<h2><a name="CHORDS_DIAGRAMS2"></a>VI. CHORDS DIAGRAMS</h2>
<pre>
Number of chords:		<a href="#integer">Integer</a>
	Number of chords to write in the chords diagram list.

Then comes the written chords list, as described in <a href="#5._Chords_diagrams">V.5 Chords diagrams</a>.</pre>
</td>
</tr>
</tbody>
</table>
<hr />This page is part of the <a target="_blank" rel="nofollow" href="http://DGuitar.sourceforge.net/"  target="_top">DGuitar Home Page</a></p>
]]></content:encoded>
			<wfw:commentRss>http://UbuntuLinux.ru/developers/protokoly/guitar-pro-4-06-file-format-description/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Путеводитель по джунглям звуковых API в Linux</title>
		<link>http://UbuntuLinux.ru/developers/protokoly/linux-sound-api-overview/</link>
		<comments>http://UbuntuLinux.ru/developers/protokoly/linux-sound-api-overview/#comments</comments>
		<pubDate>Sat, 20 Mar 2010 16:31:47 +0000</pubDate>
		<dc:creator><![CDATA[Admin]]></dc:creator>
				<category><![CDATA[Протоколы]]></category>
		<category><![CDATA[ALSA]]></category>
		<category><![CDATA[GStreamer]]></category>
		<category><![CDATA[JACK]]></category>
		<category><![CDATA[OSS]]></category>
		<category><![CDATA[PulseAudio]]></category>
		<category><![CDATA[SDL]]></category>
		<category><![CDATA[звук]]></category>

		<guid isPermaLink="false">http://manlinux.org/?p=70</guid>
		<description><![CDATA[Оригинал: A Guide Through The Linux Sound API Jungle Автор: Lennart Poettering Дата публикации: 24 сентября 2008 г. Перевод: Максим Белозеров Дата перевода: 25 августа 2009 г. Во время миниконференции, посвященной теме аудио, на конференции Linux Plumbers выяснилась одна вещь: программистам часто трудно решить, &#8230; <a href="/developers/protokoly/linux-sound-api-overview/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Оригинал: <a target="_blank" rel="nofollow" href="http://0pointer.de/blog/projects/guide-to-sound-apis.html" rel="nofollow"  target="_blank">A Guide Through The Linux Sound API Jungle</a><br />
Автор: Lennart Poettering<br />
Дата публикации: 24 сентября 2008 г.<br />
Перевод: <a target="_blank" rel="nofollow" href="http://rus-linux.net/lib.php?name=/MyLDP/trans/belozerov.koi" rel="nofollow"  target="_blank">Максим Белозеров</a><br />
Дата перевода: 25 августа 2009 г.</p>
<p>Во время <a target="_blank" rel="nofollow" href="http://lwn.net/Articles/299211/" rel="nofollow"  target="_blank">миниконференции</a>, посвященной теме аудио, на <a target="_blank" rel="nofollow" href="http://linuxplumbersconf.org/" rel="nofollow"  target="_blank">конференции Linux Plumbers</a> выяснилась одна вещь: программистам часто трудно решить, какие из звуковых API для каких целей использовать при создании аудиопрограмм для Linux. Давайте попробуем разобраться в этих джунглях:<br />
<span id="more-859"></span></p>
<h2>Что вы хотите сделать?</h2>
<ul>
<li><em>Я хочу написать еще один медиаплеер!</em></li>
<p>Используйте GStreamer! (Но если вы собираетесь писать только для KDE, тогда используйте альтернативный вариант — Phonon).</p>
<li><em>Я хочу добавить в свое приложение звуковые оповещения для событий!</em></li>
<p>Используйте libcanberra, устанавливайте звуковые файлы в соответствии со <a target="_blank" rel="nofollow" href="http://freedesktop.org/wiki/Specifications/sound-theme-spec" rel="nofollow"  target="_blank">спецификациями XDG</a> по звуковым темам и их именованию (но если вы собираетесь писать только для KDE, тогда как альтернативу можно использовать KNotify, хотя у него немного другие задачи).</p>
<li><em>Я хочу создавать профессиональные аудиоредакторы, программы для звукозаписи, работы с MIDI и синтезаторы!</em></li>
<p>Используйте JACK и (или) полный интерфейс ALSA.</p>
<li><em>Мне нужно простое воспроизведение и захват PCM-аудио!</em> <a target="_blank" rel="nofollow" href="http://useunix.ru/putevoditel-po-dzhunglyam-zvukovyx-api-v-linux/#prim" ><sup>1)</sup></a></li>
<p>Используйте <em>безопасную</em> часть ALSA.</p>
<li><em>Хочу добавить звук к своей игре!</em></li>
<p>Используйте звуковой API из SDL для полноэкранных игр, а libcanberra для простых игр со стандартным пользовательским интерфейсом типа Gtk+.</p>
<li><em>Хочу написать микшер!</em></li>
<p>Используйте уровень, с которым собираетесь непосредственно работать: если хотите обеспечить поддержку усовершенствованных программных микшеров, используйте API управления громкостью PulseAudio. Чтобы обеспечить поддержку аппаратных микшеров, используйте API микшера ALSA.</p>
<li><em>Я хочу писать аудиоприложения промежуточного уровня!</em></li>
<p>Используйте полный стек ALSA.</p>
<li><em>Мне нужно написать аудиоприложения для встроенных систем!</em></li>
<p>Для технического применения обычно подходит <em>безопасная</em> часть ALSA, но все зависит от конкретного случая.</ul>
<h2>Хотите узнать больше о различных звуковых API?</h2>
<h3>GStreamer</h3>
<p><a target="_blank" rel="nofollow" href="http://www.gstreamer.net/" rel="nofollow"  target="_blank">GStreamer</a> — стандарт де-факто для систем управления медиапотоками для рабочих станций Linux. Он поддерживает кодирование и декодирование аудио- и видеопотоков. Его можно применять для самых разных целей от простого воспроизведения аудиофайлов до сложных систем вещания по сети. GStreamer поддерживает широкий диапазон кодеков и звуковых подсистем. GStreamer не очень подходит для воспроизведения простого PCM и для приложений, работающих с малой задержкой или в реальном масштабе времени. GStreamer переносим и может использоваться не только в Linux. Среди поддерживаемых звуковых подсистем — ALSA, OSS и PulseAudio. [<a target="_blank" rel="nofollow" href="http://gstreamer.freedesktop.org/documentation/" rel="nofollow"  target="_blank">Справочник и руководство по программированию</a>]</p>
<h3>libcanberra</h3>
<p><a target="_blank" rel="nofollow" href="http://0pointer.de/lennart/projects/libcanberra/" rel="nofollow"  target="_blank">libcanberra</a> — звуковой API для абстрактных событий. В нем реализованы <a target="_blank" rel="nofollow" href="http://www.freedesktop.org/wiki/Specifications/sound-theme-spec" rel="nofollow"  target="_blank">спецификации XDG по звуковым темам и их именованию</a>. libcanberra разработана для GNOME, но сама по себе не зависит от GNOME, Gtk или GLib и может использоваться в других окружениях рабочего стола. Помимо простого интерфейса для воспроизведения аудиофайлов libcanberra обеспечивает кэширование (что весьма полезно для сетевых тонких клиентов) и позволят передавать различные метаданные звуковым подсистемам, что можно использовать для создания дополнительных удобств для пользователя (например, для озвучивания событий позиционирования) и для улучшения восприятия. libcanberra поддерживает различные звуковые подсистемы и может портироваться на системы, отличные от Linux. Среди поддерживаемых звуковых подсистем — ALSA, OSS, PulseAudio и GStreamer. [<a target="_blank" rel="nofollow" href="http://0pointer.de/lennart/projects/libcanberra/gtkdoc/" rel="nofollow"  target="_blank">Справочник по API</a>]</p>
<h3>JACK</h3>
<p><a target="_blank" rel="nofollow" href="http://jackaudio.org/" rel="nofollow"  target="_blank">JACK</a> — звуковая систем для коммутации профессиональных аудиоприложений и аппаратных выходов. Основной акцент делается на низких задержках сигнала и коммутации между приложениями. Эта система не нужна для обычного рабочего стола или для встраиваемых систем. От этого API не будет пользы, если вам требуется простое воспроизведение PCM. JACK поддерживает различные звуковые подсистемы, но лучше работает с ALSA. JACK можно переносить на другие ОС. Среди поддерживаемых звуковых подсистем — ALSA и OSS. [<a target="_blank" rel="nofollow" href="http://jackaudio.org/files/docs/html/index.html" rel="nofollow"  target="_blank">Справочник по API</a>]</p>
<h3>Полный интерфейс ALSA</h3>
<p><a target="_blank" rel="nofollow" href="http://www.alsa-project.org/" rel="nofollow"  target="_blank">ALSA</a> — это API для воспроизведения и записи PCM-аудио в Linux. ALSA в основном работает с оборудованием, хотя поддерживаются и другие звуковые подсистемы (с некоторыми ограничениями, см. ниже). Название ALSA применяется как к драйверам ядра Linux, так и к библиотеке пространства пользователя, использующей их. Библиотека ALSA полнофункциональная и переносимая (с некоторыми ограничениями). Полный API ALSA может показаться очень сложным и большим. Зато он поддерживает практически все функции современного звукового оборудования. Часть функциональности программного интерфейса ALSA ограничивается поддержкой оборудования ядром Linux (в отличие от программных звуковых серверов и драйверов пользовательского пространства, таких как аудио для Bluetooth и FireWire) и драйверами для Linux. [<a target="_blank" rel="nofollow" href="http://www.alsa-project.org/alsa-doc/alsa-lib/" rel="nofollow"  target="_blank">Справочник по API</a>]</p>
<h3>Безопасная часть ALSA</h3>
<p>Только часть полного API ALSA работает со всеми звуковыми подсистемами, поддерживаемыми ALSA. Рекомендуется придерживаться этой<em>безопасной</em> части, если вы пишете программы для ALSA, которые должны быть переносимыми, не устаревающими и совместимыми со звуковыми серверами, Bluetooth-аудио и FireWire-аудио. Ниже подробно описывается, какие из функций ALSA считаются безопасными.<em>Безопасная</em> часть API ALSA — подходящая абстракция для переносимого базового воспроизведения и записи PCM, которая используется не только для устройств, поддерживаемых драйвером ядра ALSA. Среди поддерживаемых звуковых подсистем — устройства драйвера ядра ALSA, OSS, PulseAudio и JACK.</p>
<h3>Phonon и KNotify</h3>
<p><a target="_blank" rel="nofollow" href="http://phonon.kde.org/" rel="nofollow"  target="_blank">Phonon</a> — высокоуровневая абстракция для систем потокового воспроизведения, таких как GStreamer, но этим ее функциональность не ограничивается. Поддерживается несколько звуковых подсистем. KNotify — система для “оповещений” в широком смысле, не только звуковых. Однако в ней пока не поддерживаются спецификации XDG по звуковым темам и их именованию, а также не поддерживается кэширование или передача метаданных оповещения звуковой подсистеме нижнего уровня. KNotify поддерживает разные подсистемы для воспроизведения звука через Phonon. Оба API специфичны для KDE/Qt и для приложений за пределами KDE/Qt их лучше не использовать. [<a target="_blank" rel="nofollow" href="http://api.kde.org/4.0-api/kdelibs-apidocs/phonon/html/index.html" rel="nofollow"  target="_blank">Справочник по API Phonon</a>] [<a target="_blank" rel="nofollow" href="http://api.kde.org/4.x-api/kdebase-runtime-apidocs/knotify/html/index.html" rel="nofollow"  target="_blank">Справочник по API KNotify</a>]</p>
<h3>SDL</h3>
<p><a target="_blank" rel="nofollow" href="http://www.libsdl.org/" rel="nofollow"  target="_blank">SDL</a> — переносимый API, используемый в основном для разработки полноэкранных игр. Среди прочего он включает в себя и переносимый аудиоинтерфейс. Среди звуковых подсистем, поддерживаемых SDL — OSS, PulseAudio и ALSA. [<a target="_blank" rel="nofollow" href="http://www.libsdl.org/cgi/docwiki.cgi" rel="nofollow"  target="_blank">Справочник по API</a>]</p>
<h3>PulseAudio</h3>
<p><a target="_blank" rel="nofollow" href="http://pulseaudio.org/" rel="nofollow"  target="_blank">PulseAudio</a> — звуковая система для Linux-десктопов и встроенных окружений, работающая в пространстве пользователя, обычно поверх ALSA. PulseAudio поддерживает сквозной тракт передачи, раздельный уровень громкости для разных приложений, озвучивание пространственных оповещений, позволяет на лету переключать звуковые потоки между устройствами и выполнять многие другие высокоуровневые операции. PulseAudio добавляет к аудиостеку Linux модель бесперебойного воспроизведения (см. <a target="_blank" rel="nofollow" href="http://0pointer.de/blog/projects/pulse-glitch-free.html" rel="nofollow"  target="_blank">glitch-free</a>). PulseAudio не подходит для профессиональных систем работы с аудио. PulseAudio можно портировать на системы, отличные от Linux. В PulseAudio есть собственный API, а также поддержка <em>безопасной</em> части ALSA, а также ограниченная, основанная на LD_PRELOAD совместимость с OSS. Среди поддерживаемых PulseAudio звуковых подсистем — OSS и ALSA. Также есть возможность взаимодействия с JACK. [<a target="_blank" rel="nofollow" href="http://0pointer.de/lennart/projects/pulseaudio/doxygen/" rel="nofollow"  target="_blank">Справочник по API</a>]</p>
<h3>OSS</h3>
<p><a target="_blank" rel="nofollow" href="http://www.opensound.com/" rel="nofollow"  target="_blank">Open Sound System</a> — низкоуровневый PCM API, поддерживаемый многими Unix-системами, в том числе и Linux. Сначала это была стандартная аудиосистема Linux, современные ядра Linux поддерживают третью версию API, OSS3. OSS3 считается устаревшим и был полностью заменен на ALSA. Уже появился OSS4, преемник OSS3, но практически не играет роли для Linux и не поддерживается в стандартных ядрах и распространенных дистрибутивах. OSS API работает на низком уровне, на основе прямых обращений к интерфейсам ядра с помощью ioctl(). Поэтому его неудобно использовать и практически нельзя виртуализировать для использования в аудиосистемах вне ядра, таких как звуковые серверы (например PulseAudio) или драйверы пространства пользователя (например Bluetooth- или FireWire-аудио). Модель с учетом задержек в OSS3 вообще нельзя верно преобразовать для программных звуковых серверов, а также возникают проблемы с оборудованием, подключенным не по шине PCI, например по USB. Кроме того, OSS не конвертирует, не перераспределяет или перекодирует типы дискретизации при необходимости. Это значит, что клиентские приложения, которые должны поддерживать OSS, обязаны содержать полный набор утилит для конвертации, переназначения и перекодирования на тот случай, если оборудование не поддерживает аппаратно требуемые параметры дискретизации. Среди современных звуковых карт часто встречается поддержка только S32LE на 48 кГц. Если предполагается, что клиентское приложение для OSS всегда воспроизводит звук в с дискретизацией S16LE на 44,1 кГц, ничего не выйдет. OSS3 можно портировать на другие Unix-совместимые ОС, но с учетом некоторых различий. В OSS также нет нормальной поддержки многоканального звука и другой функциональности современных аудиосистем. <strong>OSS устарел, его не следует использовать для новых приложений.</strong> В ALSA и PulseAudio есть ограниченная совместимость с OSS, основанная на LD_PRELOAD. [<a target="_blank" rel="nofollow" href="http://www.opensound.com/pguide/oss.pdf" rel="nofollow"  target="_blank">Руководство по программированию</a>]</p>
<p>Все звуковые системы и API, перечисленные выше, поддерживаются во всех популярных современных дистрибутивах. Для поддержки libcanberra может потребоваться последний выпуск вашего дистрибутива для разработчиков.</p>
<p>Все звуковые системы и API, перечисленные выше, подходят для разработки коммерческих приложений с закрытым кодом, так как они лицензированы под LGPL или более либеральными лицензиями, либо в клиентскую часть не включаются библиотеки.</p>
<h2>Когда и где стоит использовать тот или иной API?</h2>
<h3>GStreamer</h3>
<p>GStreamer хорошо подходит для высокоуровневых задач. Например, если вам надо воспроизвести аудиофайл или видеопоток, не заботясь о несущественных деталях на уровне кодеков или PCM.</p>
<h3>libcanberra</h3>
<p>libcanberra лучше всего подходит для озвучивания ввода в пользовательских интерфейсах или для воспроизведения простых звуковых файлов для оповещений.</p>
<h3>JACK</h3>
<p>JACK хорошо подходит для профессиональных программ аудиозаписи или в случаях, когда требуется перекрестная коммутация между приложениями.</p>
<h3>Полный интерфейс ALSA</h3>
<p>Полный интерфейс ALSA лучше использовать для программ “промежуточного уровня”, или если вы собираетесь использовать очень специфичные возможности оборудования, которые могут понадобиться для задач аудиозаписи.</p>
<h3>Безопасная часть ALSA</h3>
<p><em>Безопасный</em> интерфейс ALSA хорошо подходит для программ, которые занимаются записью/воспроизведением простых PCM-данных с аппаратных устройств или программных звуковых подсистем.</p>
<h3>Phonon и KNotify</h3>
<p>Phonon и KNotify стоит использовать только в приложениях KDE/Qt для высокоуровневого воспроизведения медиаданных и для простых звуковых оповещений соответственно.</p>
<h3>SDL</h3>
<p>SDL подходит для полноэкранных игр.</p>
<h3>PulseAudio</h3>
<p>На данный момент API PulseAudio следует использовать только для приложений, которые должны обеспечивать функциональность, специфичную для звукового сервера (например, микшеров) или если уровень абстракций вывода PCM уже реализован в приложении и имеет смысл добавить поддержку PulseAudio для минимизации количества уровней в аудиостеке.</p>
<h3>OSS</h3>
<p>OSS не следует использовать для новых программ.</p>
<h2>Хотите узнать больше о <em>безопасной части</em> ALSA?</h2>
<p>Вот список того, что следует и не следует делать, если вы хотите, чтобы ваши программы не устаревали и нормально работали с неаппаратными звуковыми подсистемами и низкоуровневыдрайверами пространства пользователя, такими как Bluetooth- и FireWire-аудио. Некоторые из этих рекомендаций применимы также и для полного API ALSA, но часть функциональности можно считать устаревшей в любом случае.</p>
<p>У вас должна быть серьезная причина, чтобы писать код, не соответствующий этим правилам. Иначе этот код можно будет просто считать<strong>неработоспособным</strong>!</p>
<p>Что НЕ НАДО делать:</p>
<ul>
<li><strong>Не</strong> используйте “обработчики async”, например <tt>snd_async_add_pcm_handler()</tt> и тому подобные. Асинхронные обработчики реализованы с применением сигналов POSIX, а это весьма спорное их применение, особенно для библиотек и подключаемых модулей. Даже если нежелательно ограничиваться <em>безопасной</em> частью ALSA, лучше не использовать такие функции. <a target="_blank" rel="nofollow" href="http://mailman.alsa-project.org/pipermail/alsa-devel/2008-May/008030.html" rel="nofollow"  target="_blank">Здесь подробно описывается, почему не стоит использовать сигналы для ввода-вывода звука.</a></li>
<li><strong>Не</strong> берите данные из конфигурационного файла ALSA самостоятельно или с помощью любой из функций ALSA, подобных<tt>snd_config_xxx()</tt>. Если нужно пронумеровать аудиоустройства, используйте <tt>snd_device_name_hint()</tt> (и связанные с ней функции). Только в этом API есть также поддержка нумерации виртуальных аудиоустройств и аудиоустройств с драйверами в пространстве пользователя.</li>
<li><strong>Не</strong> берите данные из файлов, расположенных в <tt>/proc/asound/</tt>. В этих файлах содержится информация только о звуковых драйверах ядра, подключаемых модулей пространства пользователя там нет. Кроме того, устройства в ядре могут отличаться от их представления в пространстве пользователя (то есть подчиненные устройства могут обозначаться не так, как устройства пространства пользователя, например <tt>surround51</tt> и аналогичные).</li>
<li><strong>Не</strong> рассчитывайте на стабильность списков устройств в ALSA. На данный момент они зависят от порядка инициализации драйверов во время загрузки и поэтому могут изменяться.</li>
<li><strong>Не</strong> используйте API <tt>snd_card_xxx()</tt>. Для нумерации используйте <tt>snd_device_name_hint()</tt> (и связанные с ней функции). Функция<tt>snd_card_xxx()</tt> устарела. Она просто перечисляет аппаратные устройства в ядре. Устройства пространства пользователя, такие как звуковые серверы и Bluetooth-аудио не поддерживаются. Функция <tt>snd_card_load()</tt> на данный момент полностью устарела.</li>
<li><strong>Не</strong> задавайте жестко в коде строки устройств, особенно <tt>hw:0</tt> или <tt>plughw:0</tt>, или даже <tt>dmix</tt> — эти устройства не определяют назначение каналов, они назначены на устройства ядра. Крайне желательно использовать для строк устройств только <tt>default</tt>. Если требуется особое переназначение каналов, правильной строкой устройств будет <tt>front</tt> для стерео, <tt>surround40</tt> для четырехканального звука 4.0,<tt>surround41</tt>, <tt>surround51</tt> и так далее. К сожалению, на данный момент ALSA определяет стандартные наименования устройств с назначением каналов только для устройств ядра. Это означает, что <tt>default</tt> можно безопасно применять только для моно- и стереопотоков. Возможно, стоит начинать строки устройств с <tt>plug:</tt>, чтобы ALSA выполнялось переформатирование, переназначение или конвертация PCM-потока, если устройство или звуковая подсистема не поддерживает требуемые параметры дискретизации.</li>
<li><strong>Не</strong> рассчитывайте, что поддерживается какой-либо тип дискретизации кроме U8, S16_LE, S16_BE, S32_LE, S32_BE, FLOAT_LE, FLOAT_BE, MU_LAW и A_LAW.</li>
<li><strong>Не</strong> используйте для синхронизации <tt>snd_pcm_avail_update()</tt>. Эта функция должна использоваться только для запроса количества байт, которое можно считать или записать в данный момент. <strong>Не</strong> используйте <tt>snd_pcm_delay()</tt> для запроса уровня заполнения буфера воспроизведения. Эта функция должна использоваться только для синхронизации. Удостоверьтесь, что вы полностью понимаете различие. Помните, что эти две функции возвращают значения, которые не взаимосвязаны непосредственно!</li>
<li><strong>Не</strong> рассчитывайте, что в органах управления микшером всегда будет информация об уровне в децибелах.</li>
<li><strong>Не</strong> рассчитывайте, что все устройства поддерживают доступ к буферу в стиле MMAP.</li>
<li><strong>Не</strong> рассчитывайте, что указатель оборудования в буфере воспроизведения (возможно, с применением mmap) отображает действительную позицию сэмпла в DAC. Могут возникать дополнительные задержки.</li>
<li><strong>Не</strong> пытайтесь с помощью собственного кода проводить восстановление после сбоев ALSA, таких как опустошение буфера. Используйте вместо этого <tt>snd_pcm_recover()</tt>.</li>
<li><strong>Не</strong> трогайте метрики буферизации и периодов, если нет необходимости выставлять особые задержки. Будьте осторожны в разработке, аккуратно обрабатывая ситуации, в которых подсистема не может выполнить ваши запросы метрик буферизации. Помните, что во многих случаях размер буфера воспроизведения не оказывает непосредственного влияния на общее значение задержки. То есть установка фиксированного размера буфера может на практике привести к гораздо большим задержкам.</li>
<li><strong>Не</strong> рассчитывайте, что функция <tt>snd_pcm_rewind()</tt> доступна и полностью работоспособна.</li>
<li><strong>Не</strong> рассчитывайте, что время, когда PCM-поток может получать новые данные, строго зависит от параметров дискретизации и буферизации и от окончательной пропускной способности. Всегда проверяйте, чтобы новые аудиоданные поступали устройству, когда оно их запрашивает, сигнализируя о доступности для записи в fd (и аналогично для захвата).</li>
<li><strong>Не</strong> используйте “простой” интерфейс <tt>snd_spcm_xxx()</tt>.</li>
<li><strong>Не</strong> используйте функций, помеченных как “устаревшие”.</li>
<li><strong>Не</strong> используйте подсистемы timer, midi, rawmidi, hwdep.</li>
</ul>
<p>Что НАДО делать:</p>
<ul>
<li>Используйте <tt>snd_device_name_hint()</tt> для нумерации аудиоустройств.</li>
<li>Используйте <tt>snd_smixer_xx()</tt> вместо чистого <tt>snd_ctl_xxx()</tt>.</li>
<li>Для синхронизации используйте <tt>snd_pcm_delay()</tt>.</li>
<li>Для проверки уровня заполнения буфера воспроизведения/захвата используйте <tt>snd_pcm_update_avail()</tt>.</li>
<li>Используйте <tt>snd_pcm_recover()</tt> для восстановления после ошибок, возвращаемых любыми функциями ALSA.</li>
<li>По возможности используйте наибольший поддерживаемый устройствами размер буфера, чтобы минимизировать энергопотребление и для защиты от выпадений звука. Используйте <tt>snd_pcm_rewind()</tt>, если нужна быстрая реакция на пользовательский ввод.</li>
</ul>
<h2>FAQ</h2>
<h3>А как насчет ESD и NAS?</h3>
<p>ESD и NAS устарели, и как API, и как звуковой демон. Не применяйте их больше в разработке.</p>
<h3>ALSA не портируется!</h3>
<p>Это неверно! На самом деле библиотека пространства пользователя относительно портируема, в нее даже входит звуковая подсистема для аудиоустройств OSS. Нет реальных причин, мешающих использовать библиотеки ALSA на других Unix-подобных системах.</p>
<h3>Для меня важнее всего переносимость! Что делать?</h3>
<p>К сожалению, пока нет PCM API, действительно портируемого (то есть на Win32), который можно было бы посоветовать. Описанные выше системы более или менее портируемы, по крайней мере на Unix-подобные ОС. Но это не значит, что для них всех доступны подходящие подсистемы. Если для вас важна переносимость на Win32 и MacOS, возможно, стоит поискать решения, не перечисленные среди рекомендаций выше, либо помочь доработать переносимость необходимых подсистем. Ни одна из систем (за исключением OSS) не привязана жестко к ядру Linux или других Unix-подобных систем.</p>
<h3>А как насчет PortAudio?</h3>
<p>Не думаю, что PortAudio — хороший API для Unix-подобных операционных систем. Не могу его рекомендовать, но решайте сами.</p>
<h3>А почему вы так ненавидите OSS4?</h3>
<p>Я ничего не ненавижу. Просто не думаю, что OSS4 — серьезный выбор, особенно для Linux. Под Linux он абсолютно бесполезен, так как есть ALSA.</p>
<h3>Вы идиот и ничего не смыслите!</h3>
<p>Совершенно верно, не смыслю. Но это не мешает мне давать советы. Ха!</p>
<h3>Я создал новый проектик, отлично реализующий уровень абстракций для аудио и мультимедиа!</h3>
<p>Извините, но этого недостаточно. Я перечисляю здесь только программы, которые точно подходят и достаточно хорошо поддерживаются.</p>
<h2>Заключение</h2>
<p>Разумеется, это только базовые рекомендации, которые могут лишь подтолкнуть в верном направлении. В каждом конкретном случае потребности разные, соответственно и не рассмотренные здесь варианты могут быть целесообразными. Только вы сами можете определить, что из написанного мной применимо для вашего приложения.</p>
<p>Здесь упоминались только те программные системы, которые считаются стабильными и были общедоступны на момент написания. Надеюсь, в будущем можно будет рассказать о более уместной и переносимой замене <em>безопасной</em> части функций ALSA. Я собираюсь периодически обновлять этот текст для внесения обновленной информации.</p>
<p>Если вы считаете, что я забыл упомянуть какое-то практическое применение или важный API, напишите мне или оставьте комментарий. Однако полагаю, что выше все изложено достаточно исчерпывающе, и если что-то пропущено, то скорее всего умышленно.</p>
<p>Кроме того, учитывайте то, что я участвую в разработке PulseAudio и libcanberra, а также вношу небольшой вклад в ALSA, GStreamer и некоторые другие из перечисленных систем. Да, я пристрастен.</p>
<p>Да, и пожалуйста, размещайте ссылки на этот материал. Я хочу, чтобы это руководство было широко известно в Linux-сообществе. Спасибо!</p>
<hr /><em><a name="prim"></a>Прим.: PCM расшифровывается как импульсно-кодовая модуляция (pulse code modulation) и обеспечивает цифровое представление аналогового сигнала, который дискретизируется (оцифровывается) через равные промежутки времени (с заданной в герцах частотой) и представляется в двоичном виде (с заданной точностью – разрядностью в битах).</em></p>
<div><span style="font-family: 'Liberation Sans', Arial, Georgia, 'Times New Roman', Times, serif; line-height: normal; font-size: 12px; color: #333333;"><em><br />
</em></span></div>
]]></content:encoded>
			<wfw:commentRss>http://UbuntuLinux.ru/developers/protokoly/linux-sound-api-overview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Команды протокола POP3 (приём почты)</title>
		<link>http://UbuntuLinux.ru/developers/protokoly/pop3-protocol-commands/</link>
		<comments>http://UbuntuLinux.ru/developers/protokoly/pop3-protocol-commands/#comments</comments>
		<pubDate>Sat, 20 Mar 2010 16:27:02 +0000</pubDate>
		<dc:creator><![CDATA[Admin]]></dc:creator>
				<category><![CDATA[Протоколы]]></category>
		<category><![CDATA[mail]]></category>
		<category><![CDATA[pop3]]></category>

		<guid isPermaLink="false">http://manlinux.org/?p=68</guid>
		<description><![CDATA[Команды протокола POP3 Команда Синтаксис Описание STAT Формат ответа: “+ОК nn mm”, где nn — количество сообщений, mm — их общий объем: С: STAT S: +ОК 2 320 В этом примере РОРЗ -сервер сообщает, что в данном почтовом ящике находятся &#8230; <a href="/developers/protokoly/pop3-protocol-commands/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><span id="more-68"></span></p>
<table border="0" cellpadding="7" width="100%" rules="all">
<tbody>
<tr>
<td colspan="3">Команды протокола POP3</td>
</tr>
<tr>
<td width="20%" valign="top">Команда</td>
<td width="40%" valign="top">Синтаксис</td>
<td width="40%" valign="top">Описание</td>
</tr>
<tr>
<td width="20%" valign="top">STAT</td>
<td width="40%" valign="top">Формат ответа: “+ОК nn mm”, где nn — количество сообщений, mm — их общий объем:</p>
<p>С: STAT</p>
<p>S: +ОК 2 320</p>
<p>В этом примере РОРЗ -сервер сообщает, что в данном почтовом ящике находятся два сообщения общим объемом 320 байт.</td>
<td width="40%" valign="top">После того как клиент успешно прошел процедуру аутентификации в РОРЗ- сервере, и РОРЗ- сервер “закрыл” определенный почтовый ящик только для использования данным клиентом (для тех, кто работал с базами данных, это называется EXCLUSIVE ACCESS LOCK), РОРЗ- сессия переходит в режим TRANSACTION, и клиент может начать работу со своей почтой</p>
<p>Команда <strong>STAT</strong><strong> </strong>(без аргументов) используется для просмотра состояния текущего почтового ящика.</p>
<p>В ответ РОРЗ- сервер возвращает строку, содержащую количество и общий размер в байтах сообщений, которые клиент может получить с РОРЗ- сервера. Сообщения, помеченные на удаление, не учитываются</td>
</tr>
<tr>
<td width="20%" valign="top">LIST [msg]</td>
<td width="40%" valign="top">С: LIST</p>
<p>S: +ОК 2 messages (320 octets)</p>
<p>S: 1 120</p>
<p>S: 2 200</p>
<p>S: .</p>
<p><em>ИЛИ</em></p>
<p>С: LIST 2</p>
<p>S: +ОК 2 200</p>
<p><em>ИЛИ</em></p>
<p><em> </em>С: LIST 3</p>
<p>S: -ERR no such message, only 2 messages in maildrop</td>
<td width="40%" valign="top">Команда <strong>LIST</strong><strong> </strong>может передаваться как с аргументом msg — номером сообщения, так и без аргумента.</p>
<p>Если команда содержит аргумент, и сообщение с указанным номером существует, ответом на нее будет “информационная строка”, которая содержит номер сообщения и размер сообщения в байтах. Если аргумент не указан — ответом будет список информационных строк обо всех сообщениях в данном почтовом ящике. Сообщения, помеченные на удаление не фигурируют в этом списке</td>
</tr>
<tr>
<td width="20%" valign="top">RETR msg</td>
<td width="40%" valign="top">С: RETR 1</p>
<p>S: +ОК 120 octets</p>
<p>S: &lt;text message&gt;</p>
<p>S: .</td>
<td width="40%" valign="top">Используется для передачи клиенту запрашиваемого сообщения. Аргумент команды — номер сообщения. Если запрашиваемого сообщения нет, возвращается отрицательный индикатор “-ERR”.</td>
</tr>
<tr>
<td width="20%" valign="top">DELE msg</td>
<td width="40%" valign="top">С: DELE 1</p>
<p>S: +ОК message 1 deleted</p>
<p>ИЛИ</p>
<p>С: DELE 2</p>
<p>S: -ERR message 2 already deleted</td>
<td width="40%" valign="top">Аргумент команды— номер сообщения. Сообщения, помеченные на удаление, реально удаляются только после закрытия транзакции, на стадии UPDATE.</td>
</tr>
<tr>
<td width="20%" valign="top">NOOP</td>
<td width="40%" valign="top">С: NOOP</p>
<p>S: +ОК</td>
<td width="40%" valign="top">Для проверки состояния соединения с РОРЗ- сервером используется команда <strong>NOOP</strong><strong> </strong>. При активном соединении ответом на нее будет положительный индикатор “+ОК”:</td>
</tr>
<tr>
<td width="20%" valign="top"><strong>RSET</strong></p>
<p><strong> </strong></td>
<td width="40%" valign="top">С: RSET</p>
<p>S: +OK maildrop has 2 messages (320 octets)</td>
<td width="40%" valign="top">Для отката транзакции внутри сессии используется команда <strong>RSET</strong><strong> </strong>(без аргументов). Если пользователь случайно Пометил на удаление какие-либо сообщения, он может убрать эти пометки, отправив эту команду:</td>
</tr>
<tr>
<td width="20%" valign="top">TOP msg n</td>
<td width="40%" valign="top">С ТОР 1 10</p>
<p>S +OK</p>
<p>S &lt;header&gt;</p>
<p>S &lt;blank&gt;</p>
<p>S &lt;message body&gt;</p>
<p>S .</td>
<td width="40%" valign="top">По этой команде пользователь может получить “n” первых строк сообщения с номером “msg”. РОРЗ- сервер по запросу клиента отправляет заголовок сообщения, затем пустую строку, затем требуемое количество строк сообщения (если количество строк в сообщении меньше указанного в параметре “n”, пользователю передается все сообщение).</td>
</tr>
<tr>
<td width="20%" valign="top">USER name</td>
<td width="40%" valign="top">С: USER frated</p>
<p>S: -ERR sorry, no mailbox for frated here</p>
<p><em>ИЛИ</em></p>
<p>С: USER mrose</p>
<p>S: +OK mrose is a real hoopy frood</td>
<td width="40%" valign="top">Когда РОРЗ -сессия находится в состоянии аутентификации (AUTHORIZATION), и клиент должен зарегистрировать себя на РОРЗ -сервере. Это может быть выполнено либо с помощью команд USER и PASS — ввод открытых пользовательского идентификатора и пароля (именно этот способ используется чаще), либо командой АРОР — аутентификация цифровой подписью, на базе секретного ключа. Любой РОРЗ -сервер должен поддерживать хотя бы один из механизмов аутентификации.</p>
<p>Аргументом — “name” является строка, идентифицирующая почтовый ящик системы. Этот идентификатор должен быть уникальным в данной почтовой системе РОРЗ -сервера. Если ответом на эту команду является строка индикатора “+OK”, клиент может отправлять команду PASS — ввод пароля или QUIT — завершить сессию. Если ответом является строка “-ERR”, клиент может либо повторить команду USER, либо закрыть сессию</td>
</tr>
<tr>
<td width="20%" valign="top">PASS string</td>
<td width="40%" valign="top">С: USER mrose</p>
<p>S: +OK mrose is a real hoopy frood</p>
<p>С: PASS secret</p>
<p>S: -ERR maildrop already locked</p>
<p><em>ИЛИ</em></p>
<p>С: USER mrose</p>
<p>S: +OK mrose is a real hoopy frood</p>
<p>C: PASS secret</p>
<p>S: +OK mrose’s maildrop has 2 messages (320 octets)</td>
<td width="40%" valign="top">Аргументом команды является строка пароля данного почтового ящика. После получения команды PASS, РОРЗ -сервер, на основании аргументов команд USER и PASS, определяет возможность доступа к заданному почтовому ящику. Если РОРЗ -сервер ответил “+OK”, это означает, что аутентификация клиента прошла успешно и он может работать со своим почтовым ящиком, т. е. сессия переходит в состояние TRANSACTION. Если РОРЗ- сервер ответил “-ERR”, то либо был введен неверный пароль, либо не найден указанный почтовый ящик</td>
</tr>
<tr>
<td width="20%" valign="top">АРОР name digest</td>
<td width="40%" valign="top">S: +OK РОРЗ server ready 1896.697170952@dbc.mtview.ca.us</p>
<p>С: АРОР mrose c4c9334bac560ecc979e58001b3e22fb</p>
<p>S: +OK maildrop has 1 message (369 octets)</p>
<p>Алгоритм на основании открытого ключа “tanstaaf и временной метки</p>
<p><sup>&lt;</sup> 1896.697170952@dbc.rnt.view.ca.us&gt; построил шифрованную строку “c4c9334bac560ecc979e5800Ib3e22fb”.</td>
<td width="40%" valign="top">Команда аутентификации пользователя <strong>АРОР</strong> не входит в список обязательно реализуемых команд РОРЗ -сервера. Эта команда предоставляет значительно больший (по сравнению с командами USER или PASS) уровень защиты аутентификации пользователя при открытии сессии AUTHORIZATION и используется только тогда, когда к обеспечению конфиденциальности доступа к информации почтовых ящиков предъявляются повышенные требования. Эта команда может быть передана клиентом РОРЗ -сервера после получения приветственного сообщения или после ошибки обработки команд USER/PASS.</p>
<p>Аргументами команды являются: name — имя пользователя (то же, что и в команде USER), digest — шифрованная (по алгоритму MD5) строка пароля. Применяемый здесь алгоритм необратимого шифрования для построения секретного ключа использует открытый ключ и временную метку. Временные метки передаются хосту клиента вместе с сообщением приветствия. Например, для UNIX-машин временная метка может иметь вид: &lt;process-ID.clock@hostname&gt;, где process-ID — это идентификатор процесса, clock — состояние таймера на момент установления соединения, hostname — имя компьютера РОРЗ -сервера. Этот механизм позволяет достичь очень высокой степени защищенности. Далее показан пример работы команды АРОР</td>
</tr>
<tr>
<td width="20%" valign="top"><strong> </strong><strong>QUIT</strong><strong> </strong></td>
<td width="40%" valign="top">С: QUIT</p>
<p>S: +ОК dewey POP3 server signing off</td>
<td width="40%" valign="top">К командам состояния AUTHORIZATION может относиться команда закрытия РОРЗ- сессии — <strong>QUIT</strong><strong> </strong>, если она была отправлена в режиме AUTHORIZATION (например, при вводе неправильного пароля или идентификатора пользователя):</p>
<p>Эта команда отправляется без аргументов и всегда имеет единственный ответ “+ОК”.</td>
</tr>
<tr>
<td colspan="3">Пример сценария работы с POP-сервером</td>
</tr>
<tr>
<td colspan="3" valign="top"><em>Ниже приведена стандартная сессия работы с РОРЗ -протоколом.</em><br />
S: &lt;wait for connection on TCP port 110&gt;</p>
<p>C: &lt;open connection&gt;</p>
<p>S: +OK РОРЗ server ready</p>
<p>С: USER<strong> </strong>mrose</p>
<p>S: +OK mrose is a real hoopy frood</p>
<p>С: PASS secret</p>
<p>S: +OK mrose’s maildrop has 2 messages (320 octets)</p>
<p>С: STAT</p>
<p>S: +OK 2 320</p>
<p>С: LIST</p>
<p>S: +OK 2 messages (320 octets)</p>
<p>S: 1 120</p>
<p>S: 2 200</p>
<p>S: .</p>
<p>С: RETR 1</p>
<p>S: +OK 120 octets</p>
<p>S: &lt;the РОРЗ server sends message 1&gt;</p>
<p>S: .</p>
<p>С: DELE 1</p>
<p>S: +OK message 1 deleted</p>
<p>С: RETR 2</p>
<p>S: +OK 200 octets</p>
<p>S: &lt;the РОРЗ server sends message 2&gt;</p>
<p>S: .</p>
<p>С: DELE 2</p>
<p>S: +OK message 2 deleted</p>
<p>С: QUIT</p>
<p>S: +OK dewey РОРЗ server signing off (maildrop empty)</p>
<p>С: &lt;close connection&gt;</p>
<p>S: &lt;wait for next connection&gt;</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://UbuntuLinux.ru/developers/protokoly/pop3-protocol-commands/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zenity – создание GTK+ интерфейсов из консоли</title>
		<link>http://UbuntuLinux.ru/developers/zenity-creating-gtk-interface-from-the-console/</link>
		<comments>http://UbuntuLinux.ru/developers/zenity-creating-gtk-interface-from-the-console/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 14:30:45 +0000</pubDate>
		<dc:creator><![CDATA[Admin]]></dc:creator>
				<category><![CDATA[Разработка под Linux]]></category>
		<category><![CDATA[Gtk+]]></category>
		<category><![CDATA[zenity]]></category>

		<guid isPermaLink="false">http://manlinux.org/?p=43</guid>
		<description><![CDATA[Классная утилита создания графических интерфейсов прямо из sh скриптов. Пользоваться ей просто: zenity [OPTION...] Для начала вызов help’а: -?, --help Показать параметры справки --help-all Показать все параметры справки --help-general Показывать общие параметры --help-calendar Показывать параметры календаря --help-entry Показывать параметры ввода &#8230; <a href="/developers/zenity-creating-gtk-interface-from-the-console/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Классная утилита создания графических интерфейсов прямо из sh скриптов. Пользоваться ей просто:</p>
<pre>zenity [OPTION...]</pre>
<p>Для начала вызов help’а:<br />
<span id="more-851"></span></p>
<pre> -?, --help                      Показать параметры справки
 --help-all                      Показать все параметры справки
 --help-general                  Показывать общие параметры
 --help-calendar                 Показывать параметры календаря
 --help-entry                    Показывать параметры ввода текста
 --help-error                    Показывать параметры диалога вывода ошибки
 --help-info                     Показывать параметры диалога вывода информации
 --help-file-selection           Показывать параметры диалога выбора файлов
 --help-list                     Показывать параметры списка
 --help-notification             Показывать параметры значка уведомления
 --help-progress                 Показывать параметры хода процесса
 --help-question                 Показывать параметры запроса
 --help-warning                  Показывать параметры диалога для вывода предупреждения
 --help-scale                    Показывать параметры масштаба
 --help-text-info                Показывать параметры текстовой информации
 --help-misc                     Показывать прочие параметры
 --help-gtk                      Показать параметры GTK+</pre>
<p>Ну и непосредственно параметры для отрисовки GTK окна</p>
<pre> --calendar                      Отобразить диалог для выбора даты
 --entry                         Отобразить диалог для ввода текста
 --error                         Отобразить диалог для вывода ошибки
 --info                          Отобразить диалог для вывода информации
 --file-selection                Отобразить диалог для выбора файла
 --list                          Отобразить диалог со списком
 --notification                  Отобразить диалог уведомления
 --progress                      Отобразить диалог хода процесса
 --question                      Отобразить диалог с вопросом
 --warning                       Отобразить диалог с предупреждением
 --scale                         Отобразить диалог масштаба
 --text-info                     Отобразить диалог с текстовой информацией
 --display=DISPLAY               X display to use</pre>
<p>Примеры:<br />
<code>zenity --info --title="Пример" --text="Это текст для примера"</code><br />
<a title="zenity info example" href="/wp-content/uploads/2010/03/zenity1.png"><img src="/wp-content/uploads/2010/03/zenity1.png" alt="zenity info example" border="0" /></a><br />
<code>ls `zenity --entry --title="Пример ввода" --text="Напишите, например '/media':"`</code><br />
(zenity выводит в консоль содержимое поля, как на примере – если ввести путь, то zenity передаст его команде “ls”)<br />
<a title="zenity entry example" href="/wp-content/uploads/2010/03/zenity2.png" rel="nofollow"><img src="/wp-content/uploads/2010/03/zenity2.png" alt="zenity entry example" border="0" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://UbuntuLinux.ru/developers/zenity-creating-gtk-interface-from-the-console/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Как работать с базами данных в Python</title>
		<link>http://UbuntuLinux.ru/developers/how-to-work-with-databases-in-python/</link>
		<comments>http://UbuntuLinux.ru/developers/how-to-work-with-databases-in-python/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 14:23:41 +0000</pubDate>
		<dc:creator><![CDATA[Admin]]></dc:creator>
				<category><![CDATA[Разработка под Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://manlinux.org/?p=41</guid>
		<description><![CDATA[Предполагается, что сам Python уже установлен и читатель владеет основами языка. Устанавливаем модуль для работы с базами данных. Таких модулей несколько, мы будем использовать MySQLdb (пакет называетсяpython-mysqldb). В Ubuntu достаточно сделать apt-get install python-mysqldb , чтобы установить данный пакет. Когда пакет &#8230; <a href="/developers/how-to-work-with-databases-in-python/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><span id="more-850"></span></p>
<ol>
<li>Предполагается, что сам Python уже установлен и читатель владеет основами языка.</li>
<li>Устанавливаем модуль для работы с базами данных. Таких модулей несколько, мы будем использовать MySQLdb (пакет называется<code>python-mysqldb</code>). В Ubuntu достаточно сделать <code>apt-get install python-mysqldb</code> , чтобы установить данный пакет.</li>
<li>Когда пакет установлен, можно начать его использование. Для этого нужно его импортировать в наш код:
<pre>import _mysql</pre>
</li>
<li>Чтобы подключиться к базе данных используйте
<pre>db = _mysql.connect("localhost","user","password","dbname");</pre>
</li>
<li>Отправляем запрос базе командой
<pre>db.query("""SELECT * FROM table""")</pre>
</li>
<li>Принимаем ответ от базы с помощью <code>answ = db.store_result()</code> или<code>answ = db.use_result()</code>. Разница этих двух методов в том, что первый получит сразу весь ответ базы, а второй будет получать его построчно(с сервера). Визуально они выглядят одинаково: и первый и второй при вызове будут отдавать по одной записи (строке), но в реальности store_result() один лишь раз обратится к базе(и сразу весь ответ будет держать у себя), а db.use_result() будет построчно спрашивать у сервера баз данных.</li>
<li>Для реального получения данных используем <code>answ.fetch_row()</code>. При каждом вызове будет выводиться кортеж кортежей полей. То есть
<pre>(('поле 1', 'поле 2', … ,'поле n'),)</pre>
</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://UbuntuLinux.ru/developers/how-to-work-with-databases-in-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PEP8 коротко и по-русски</title>
		<link>http://UbuntuLinux.ru/developers/pep8-briefly-and-in-russian/</link>
		<comments>http://UbuntuLinux.ru/developers/pep8-briefly-and-in-russian/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 12:57:23 +0000</pubDate>
		<dc:creator><![CDATA[Admin]]></dc:creator>
				<category><![CDATA[Разработка под Linux]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://manlinux.org/?p=28</guid>
		<description><![CDATA[PEP8 – это стилевые правила для кода на языке Python. используйте 4 пробела для отступа и не используйте табы, не смешивайте их максимальная длина строки 79 символов; для разрыва строки используйте отступы или бэкслеш функции верхнего уровня и определения классов &#8230; <a href="/developers/pep8-briefly-and-in-russian/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><a target="_blank" rel="nofollow" href="http://www.python.org/dev/peps/pep-0008/" rel="nofollow"  target="_blank">PEP8</a> – это стилевые правила для кода на языке Python.<br />
<span id="more-845"></span></p>
<ul>
<li>используйте 4 пробела для отступа и не используйте табы, не смешивайте их</li>
<li>максимальная длина строки 79 символов; для разрыва строки используйте отступы или бэкслеш</li>
<li>функции верхнего уровня и определения классов отделяйте двумя пустыми строками</li>
<li>определения методов внутри класса отделяйте одной пустой строкой</li>
<li>дополнительные пустые строки используйте для логической группировки методов</li>
<li>кодировка файлов должна быть Latin-1, а в Питоне 3 и выше – utf-8</li>
<li>каждый импортируемый модуль с новой строки</li>
<li>порядок импортов: стандартные модули, third-party модули, локальные модули приложения</li>
<li>пустая строка между каждой группой импортов</li>
<li>избегайте лишних пробелов внутри скобок; перед запятыми, точкой с запятой и двоеточиями</li>
<li>избегайте лишних пробелов перед скобками с аргументами функций и скобками с индексами</li>
<li>избегайте больше чем одного пробела между операторами (= – + итд)</li>
<li>используйте одиночный пробел для выделения операторов</li>
<li>избегайте пробелов вокруг ‘=’, который используется для параметров по-умолчанию и keyword аргументов</li>
<li>обновляйте комментарии вместе с кодом</li>
<li>пишите комментарии по-английски</li>
<li>избегайте имён из одиночных l, O, I</li>
<li>для модулей и пакетов используйте короткие <code>всестрочные</code> имена</li>
<li>для классов используйте <code>СловаНачинаютсяЗаглавными</code> имена</li>
<li>для функций используйте <code>слова_с_подчёркиваниями</code> (или <code>смешанныйРегистр</code> если так получилось исторически)</li>
<li>для методов используйте <code>слова_с_подчёркиваниями</code> имена</li>
<li>для внутренних методов и переменных <code>_подчёркивание_перед_словом</code></li>
<li>для проверки на <code>None</code> используйте <code>is</code> или <code>is not</code>, не используйте операторы сравнения</li>
<li>используйте исключения основанные на классах — наследованные от Exception</li>
<li>используйте методы класса string вместо строковых функций</li>
<li>используйте ”.startswith() и ”.endswith() вместо вырезки из строк для проверки префиксов и суффиксов</li>
<li>используйте isinstance() для проверки типа</li>
<li>не сравнивайте булевы переменные с True и False</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://UbuntuLinux.ru/developers/pep8-briefly-and-in-russian/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django. Как начать: развёртка, поднятие</title>
		<link>http://UbuntuLinux.ru/developers/django-how-to-install-and-start/</link>
		<comments>http://UbuntuLinux.ru/developers/django-how-to-install-and-start/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 12:50:55 +0000</pubDate>
		<dc:creator><![CDATA[Admin]]></dc:creator>
				<category><![CDATA[Разработка под Linux]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://manlinux.org/?p=25</guid>
		<description><![CDATA[Django – классный фреймвор на python’е. Более подробная информация – в гугле или позже (если и будет описание от меня – то в отдельной заметке). Эта заметка – “почеркушки на полях”, дабы быстро вспомнить как оно разворачивается. Нужен python (во &#8230; <a href="/developers/django-how-to-install-and-start/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><em>Django – классный фреймвор на python’е. Более подробная информация – в гугле или позже (если и будет описание от меня – то в отдельной заметке). Эта заметка – “почеркушки на полях”, дабы быстро вспомнить как оно разворачивается.</em><br />
<span id="more-25"></span></p>
<ol>
<li>Нужен <a target="_blank" rel="nofollow" href="http://www.python.org/download/" rel="nofollow"  target="_blank">python</a> (во время написания этих строк существовали ветки 2.6 и 3. Django написан для 2.x. Я использую 2.5.2).</li>
<li>Качаем <a target="_blank" rel="nofollow" href="http://www.djangoproject.com/download/" rel="nofollow"  target="_blank">Django</a>.</li>
<li>Устанавливаем Django:
<ol type="a">
<li><code>tar xzvf Django-*</code></li>
<li><code>cd Django-*</code></li>
<li><code>sudo python setup.py install</code></li>
</ol>
</li>
<li> Проверка: запускаем python в консоли, скармливаем код
<pre>&gt;&gt;&gt; import django
&gt;&gt;&gt; django.VERSION
(1, 1, 1, 'final', 0)</pre>
</li>
<li>Учим питон общаться с базой данных (в моём случае – MySQL):
<pre>sudo aptitude install python-mysqldb</pre>
</li>
<li> Создаём проект:
<pre>mkdir ~/django
cd ~/django
django-admin.py startproject site</pre>
<p>В результате создастся папка ~/django/site следующего содержания:</p>
<pre>site/
    __init__.py
    manage.py
    settings.py
    urls.py</pre>
<ul type="disc">
<li><code>__init__.py</code>: Файл необходим для того, чтобы Python рассматривал данный каталог как пакет, т.е., как группу модулей. Это пустой файл и обычно вам не требуется добавлять что-либо в него.</li>
<li><code>manage.py</code>: Это утилита командной строки, которая позволяет вам взаимодействовать с проектом различными методами. Наберите <strong>python manage.py help</strong> для получения информации о возможностях утилиты. Вы не должны изменять содержимое данного файла, он создан в данном каталоге в целях удобства.</li>
<li><code>settings.py</code>: Настройки для текущего проекта Django. Посмотрите на содержимое файла, чтобы иметь представление о типах доступных параметров и их значениях по умолчанию.</li>
<li><code>urls.py</code>: Описания URL для текущего проекта Django, так сказать «оглавление» для вашего сайта. <span style="color: #ff0000;">На момент создания должен быть пустым </span>(В моём случае это было не так. Было много закомменченных строк).</li>
</ul>
</li>
<li>Запускаем сервер (выделяем под это дело отдельную консольку):
<pre>cd ~/django/site
python manage.py runserver</pre>
</li>
<li>Сервак поднят на localhost’е, 8000ом порту. Можете проверить, набрав http://localhost:8000/ в браузере.
<div style="border: 1px solid red; margin: 10px 0px; padding: 10px;"><strong>Achtung!</strong> этот сервак не боевой, а тренировочный. Может обслуживать лишь 1 запрос в единицу времени. Как установить Django на нормальный? – Сначала напишите что-нибудь стоящее, а потом уже и задавайтесь этим вопросом. Пока что скажу, что это делается несложно.</div>
</li>
<li> Создаём прилагу:
<pre>cd ~/django/site
python manage.py startapp application</pre>
<p>Где вместо “application” – имя вашей прилаги (по-сути – название папки, в которой она будет лежать)</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://UbuntuLinux.ru/developers/django-how-to-install-and-start/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
