page working... This is more documented in NOTES.md, which will be committed shortly.. Slight modifications to Tufte to have some space on the right, and add a custom.css to style the tags a bit better... We can drop article.j2 as it was a test and isn't needed anymore, and macros.j2 is empty now, and may be used for other things in the future...main
@@ -0,0 +1,36 @@ | |||||
--- | |||||
title: Python ctypes wrapper for FLAC | |||||
description: > | |||||
Python ctypes wrapper for FLAC | |||||
created: !!timestamp '2014-03-15' | |||||
tags: | |||||
- Python | |||||
- FLAC | |||||
- audio | |||||
--- | |||||
As many people know, I've a fan of Python and I have been using it for | |||||
over 15 years now. | |||||
One of the recent improvements that Python has made is the inclusion of | |||||
ctypes, which allows you to write a wrapper around shared libraries in | |||||
Python making it much easier to integrate libraries. Previously you'd | |||||
have to know the C Python API to get a module. There was SWIG, but if | |||||
the library was complicated, it'd often not produce working code and even | |||||
if it did, you'd have to hand tweak the output to get it to work the way | |||||
you think it should. | |||||
One of the projects I've worked on is a UPnP media server. One of the | |||||
features it has is the ability to decode a flac file and support seeking | |||||
with in the file. | |||||
I have now released a package of the code: | |||||
[ctflac-1.0.tar.gz](https://www.funkthat.com/~jmg/releases/ctflac-1.0.tar.gz). | |||||
The one issue w/ ctypes is that some code can be very slow in Python. | |||||
The FLAC library presents the sample data as arrays for each channel, | |||||
though most libraries interleave the channel data. I have written a very | |||||
small library (that is optional) interleave.c that does this interleaving | |||||
in faster C code. In my tests, using the C code results in about a third of the CPU usage. | |||||
Hope this is useful for others! |
@@ -0,0 +1,9 @@ | |||||
ul.tags { | |||||
list-style-type: none; | |||||
} | |||||
ul.tags li { | |||||
padding-left: .5em; | |||||
padding-right: .5em; | |||||
display: inline-block; | |||||
} |
@@ -45,7 +45,7 @@ html { | |||||
} | } | ||||
body { | body { | ||||
width: 87.5%; | |||||
width: 83.5%; | |||||
margin-left: auto; | margin-left: auto; | ||||
margin-right: auto; | margin-right: auto; | ||||
padding-left: 12.5%; | padding-left: 12.5%; | ||||
@@ -114,6 +114,7 @@ article { | |||||
} | } | ||||
section { | section { | ||||
padding-right: 5%; | |||||
padding-top: 1rem; | padding-top: 1rem; | ||||
padding-bottom: 1rem; | padding-bottom: 1rem; | ||||
} | } | ||||
@@ -343,7 +344,7 @@ h3 > code { | |||||
pre > code { | pre > code { | ||||
font-size: 0.9rem; | font-size: 0.9rem; | ||||
width: 52.5%; | |||||
width: 77.5%; | |||||
margin-left: 2.5%; | margin-left: 2.5%; | ||||
overflow-x: auto; | overflow-x: auto; | ||||
display: block; | display: block; | ||||
@@ -1,28 +0,0 @@ | |||||
<article class="post"> | |||||
<h1><a class="no-tufte-underline" href="{{ res.url }}">{{ res.meta.title }}</a></h1> | |||||
<p>Posted: {{ res.meta.created.strftime('%B %e, %Y') }}</p> | |||||
{% if res.meta.tags %} | |||||
<ul class="tags clear"> | |||||
{% for tag in res.meta.tags %} | |||||
<li> | |||||
<a class="small" href="{{ content_url('blog/tags/'~tag~'.html') }}"> | |||||
{{ tag }} | |||||
</a> | |||||
</li> | |||||
{% endfor %} | |||||
</ul> | |||||
{% endif %} | |||||
<div class="clear"/> | |||||
{% refer to res.relative_path as post %} | |||||
{{ post.post|markdown|typogrify }} | |||||
{# | |||||
{% filter markdown|typogrify -%} | |||||
{% mark post -%} | |||||
{% block post -%}{%- endblock %} | |||||
{%- endmark %} | |||||
{%- endfilter %} | |||||
#} | |||||
</article> |
@@ -47,6 +47,7 @@ | |||||
<meta name="viewport" content="{{ resource.meta.viewport }}"> | <meta name="viewport" content="{{ resource.meta.viewport }}"> | ||||
{% block css %} | {% block css %} | ||||
<link rel="stylesheet" href="{{ media_url('css/custom.css') }}"> | |||||
<link rel="stylesheet" href="{{ media_url('css/tufte.css') }}"> | <link rel="stylesheet" href="{{ media_url('css/tufte.css') }}"> | ||||
{% endblock css %} | {% endblock css %} | ||||
{% block endhead %}{% endblock endhead %} | {% block endhead %}{% endblock endhead %} | ||||
@@ -67,7 +68,7 @@ | |||||
<footer> | <footer> | ||||
<div class="footer"> | <div class="footer"> | ||||
<div class="contact"> | <div class="contact"> | ||||
<ul> | |||||
<ul class="tags"> | |||||
<li><a href="https://twitter.com/{{ site.context.tweet_via }}">Twitter</a></li> | <li><a href="https://twitter.com/{{ site.context.tweet_via }}">Twitter</a></li> | ||||
</ul> | </ul> | ||||
</div> | </div> | ||||
@@ -2,17 +2,14 @@ | |||||
{% extends "base.j2" %} | {% extends "base.j2" %} | ||||
{% block main -%} | {% block main -%} | ||||
starting test | |||||
{% include "article.j2" %} | |||||
ending test | |||||
{% mark post -%} | |||||
<article class="post"> | <article class="post"> | ||||
<h1><a class="no-tufte-underline" href="{{ resource.url }}">{{ resource.meta.title }}</a></h1> | <h1><a class="no-tufte-underline" href="{{ resource.url }}">{{ resource.meta.title }}</a></h1> | ||||
<p>Posted: {{ resource.meta.created.strftime('%B %e, %Y') }}</p> | <p>Posted: {{ resource.meta.created.strftime('%B %e, %Y') }}</p> | ||||
{{ resource.meta.created.tz }} | |||||
{% if resource.meta.tags %} | {% if resource.meta.tags %} | ||||
<ul class="tags clear"> | <ul class="tags clear"> | ||||
{% for tag in resource.meta.tags %} | {% for tag in resource.meta.tags %} | ||||
@@ -26,10 +23,9 @@ ending test | |||||
{% endif %} | {% endif %} | ||||
<div class="clear"/> | <div class="clear"/> | ||||
{% filter markdown|typogrify -%} | {% filter markdown|typogrify -%} | ||||
{% mark post -%} | |||||
{% block post -%}{%- endblock %} | {% block post -%}{%- endblock %} | ||||
{%- endmark %} | |||||
{%- endfilter %} | {%- endfilter %} | ||||
</article> | </article> | ||||
{%- endmark %} | |||||
{%- endblock %} | {%- endblock %} |
@@ -1,21 +1,15 @@ | |||||
{% extends "base.j2" %} | {% extends "base.j2" %} | ||||
{% from "macros.j2" import render with context %} | |||||
{% block main %} | {% block main %} | ||||
<!-- | <!-- | ||||
{% block page_title %}<h1 class="title">{{ resource.meta.title }}</h1>{% endblock %} | {% block page_title %}<h1 class="title">{{ resource.meta.title }}</h1>{% endblock %} | ||||
--> | --> | ||||
{% for res in resource.node.walk_resources_sorted_by_time()[0:1] %} | |||||
block test | |||||
prerender macro | |||||
{% for res in resource.node.walk_resources_sorted_by_time()[0:3] %} | |||||
{% include "article.j2" %} | |||||
old data | |||||
<h1><a href="{{ res.relative_path }}">{{ res.meta.title }}</a></h1> | |||||
{% refer to res.relative_path as post %} | {% refer to res.relative_path as post %} | ||||
{{ post.post|markdown|typogrify }} | |||||
{{ post.post }} | |||||
{% endfor %} | {% endfor %} | ||||
{% endblock %} | {% endblock %} |
@@ -1,31 +0,0 @@ | |||||
{% macro render(res) %} | |||||
{% refer to res.relative_path as post %} | |||||
<article class="post"> | |||||
<h1><a class="no-tufte-underline" href="{{ res.url }}">{{ res.meta.title }}</a></h1> | |||||
<p>Posted: {{ res.meta.created.strftime('%B %e, %Y') }}</p> | |||||
{% if res.meta.tags %} | |||||
<ul class="tags clear"> | |||||
{% for tag in res.meta.tags %} | |||||
<li> | |||||
<a class="small" href="{{ content_url('blog/tags/'~tag~'.html') }}"> | |||||
{{ tag }} | |||||
</a> | |||||
</li> | |||||
{% endfor %} | |||||
</ul> | |||||
{% endif %} | |||||
<div class="clear"/> | |||||
{% refer to res.relative_path as post %} | |||||
{{ post.post|markdown|typogrify }} | |||||
{# | |||||
{% filter markdown|typogrify -%} | |||||
{% mark post -%} | |||||
{% block post -%}{%- endblock %} | |||||
{%- endmark %} | |||||
{%- endfilter %} | |||||
#} | |||||
</article> | |||||
{% endmacro %} |