summaryrefslogtreecommitdiff
path: root/community/jack2/ffado_setbuffsize-jack2.patch
blob: 0c74aad2447b9c58ce47ba37eac5c5c218ca1c19 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
From 96e0251234a29a1360c05d5d7dc98b83436b8183 Mon Sep 17 00:00:00 2001
From: Adrian Knoth <adi@drcomp.erfurt.thur.de>
Date: Sat, 17 Mar 2012 22:36:30 +0100
Subject: [PATCH] [firewire] Allow FFADO backend to change the buffer size

This is a port of Jonathan Woithe's patch from jackd1.
With sufficiently recent versions of FFADO, it allows to change
the buffersize at runtime.
---
 linux/firewire/JackFFADODriver.cpp |   65 ++++++++++++++++++++++++++++++++----
 linux/firewire/JackFFADODriver.h   |    6 ++++
 2 files changed, 65 insertions(+), 6 deletions(-)

diff --git a/linux/firewire/JackFFADODriver.cpp b/linux/firewire/JackFFADODriver.cpp
index b33e1cd..085b78a 100644
--- a/linux/firewire/JackFFADODriver.cpp
+++ b/linux/firewire/JackFFADODriver.cpp
@@ -3,6 +3,7 @@
 Copyright (C) 2004 Grame
 Copyright (C) 2007 Pieter Palmers
 Copyright (C) 2009 Devin Anderson
+Copyright (C) 2012 Jonathan Woithe, Adrian Knoth
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -48,7 +49,10 @@
 namespace Jack
 {
 
+// Basic functionality requires API version 8.  If version 9 or later
+// is present the buffers can be resized at runtime.
 #define FIREWIRE_REQUIRED_FFADO_API_VERSION 8
+#define FIREWIRE_REQUIRED_FFADO_API_VERSION_FOR_SETBUFSIZE 9
 
 #define jack_get_microseconds GetMicroSeconds
 
@@ -281,19 +285,68 @@
 int
 JackFFADODriver::SetBufferSize (jack_nframes_t nframes)
 {
-    printError("Buffer size change requested but not supported!!!");
+    ffado_driver_t* driver = (ffado_driver_t*)fDriver;
+    signed int chn;
+
+    // The speed of this function isn't critical; we can afford the
+    // time to check the FFADO API version.
+    if (ffado_get_api_version() < FIREWIRE_REQUIRED_FFADO_API_VERSION_FOR_SETBUFSIZE ||
+		    ffado_streaming_set_period_size == NULL) {
+	    printError("unsupported on current version of FFADO; please upgrade FFADO");
+	    return -1;
+    }
 
-    /*
     driver->period_size = nframes;
     driver->period_usecs =
             (jack_time_t) floor ((((float) nframes) / driver->sample_rate)
                                  * 1000000.0f);
-    */
+
+
+    // Reallocate the null and scratch buffers.
+    driver->nullbuffer = (ffado_sample_t*) calloc(driver->period_size, sizeof(ffado_sample_t));
+    if(driver->nullbuffer == NULL) {
+	    printError("could not allocate memory for null buffer");
+	    return -1;
+    }
+    driver->scratchbuffer = (ffado_sample_t*) calloc(driver->period_size, sizeof(ffado_sample_t));
+    if(driver->scratchbuffer == NULL) {
+	    printError("could not allocate memory for scratch buffer");
+	    return -1;
+    }
+
+    // MIDI buffers need reallocating
+    for (chn = 0; chn < driver->capture_nchannels; chn++) {
+	    if(driver->capture_channels[chn].stream_type == ffado_stream_type_midi) {
+		    // setup the midi buffer
+		    if (driver->capture_channels[chn].midi_buffer != NULL)
+			    free(driver->capture_channels[chn].midi_buffer);
+		    driver->capture_channels[chn].midi_buffer = (ffado_sample_t*) calloc(driver->period_size, sizeof(uint32_t));
+	    }
+    }
+    for (chn = 0; chn < driver->playback_nchannels; chn++) {
+	    if(driver->playback_channels[chn].stream_type == ffado_stream_type_midi) {
+		    if (driver->playback_channels[chn].midi_buffer != NULL)
+			    free(driver->playback_channels[chn].midi_buffer);
+		    driver->playback_channels[chn].midi_buffer = (ffado_sample_t*) calloc(driver->period_size, sizeof(uint32_t));
+	    }
+    }
+
+    // Notify FFADO of the period size change
+    if (ffado_streaming_set_period_size(driver->dev, nframes) != 0) {
+	    printError("could not alter FFADO device period size");
+	    return -1;
+    }
+
+    // This is needed to give the shadow variables a chance to
+    // properly update to the changes.
+    sleep(1);
 
     /* tell the engine to change its buffer size */
-    //driver->engine->set_buffer_size (driver->engine, nframes);
+    JackAudioDriver::SetBufferSize(nframes);  // Generic change, never fails
 
-    return -1; // unsupported
+    UpdateLatencies();
+
+    return 0;
 }
 
 typedef void (*JackDriverFinishFunction) (jack_driver_t *);
@@ -306,7 +359,7 @@
 
     assert(params);
 
-    if (ffado_get_api_version() != FIREWIRE_REQUIRED_FFADO_API_VERSION) {
+    if (ffado_get_api_version() < FIREWIRE_REQUIRED_FFADO_API_VERSION) {
         printError("Incompatible libffado version! (%s)", ffado_get_version());
         return NULL;
     }
diff --git a/linux/firewire/JackFFADODriver.h b/linux/firewire/JackFFADODriver.h
index cb2a45d..790f4dd 100644
--- a/linux/firewire/JackFFADODriver.h
+++ b/linux/firewire/JackFFADODriver.h
@@ -82,6 +82,12 @@ class JackFFADODriver : public JackAudioDriver
         int Read();
         int Write();
 
+        // BufferSize can be changed
+        bool IsFixedBufferSize()
+        {
+            return false;
+        }
+
         int SetBufferSize(jack_nframes_t nframes);
 };
 
-- 
1.7.10