History

add smoothing setting to period detection, add default smoothing to period detection in autotune

Matthew Wang committed 6 years ago

Commit bfd2c2b1 parent 55ef84e5 files · +74 −154Browse files

Unified · Split

5 files
  1. LEAF/Inc/leaf-analysis.h +7 −1
  2. LEAF/Inc/leaf-effects.h +1 −0
  3. LEAF/Src/leaf-analysis.c +22 −29
  4. LEAF/Src/leaf-effects.c +11 −99
  5. LEAF_JUCEPlugin/Source/MyTest.cpp +33 −25
LEAF/Inc/leaf-analysis.h+7−1
@@ -19,6 +19,7 @@ extern "C" { · 18 unmodified lines
19#include "leaf-mempool.h"19#include "leaf-mempool.h"
20#include "leaf-math.h"20#include "leaf-math.h"
21#include "leaf-filters.h"21#include "leaf-filters.h"
22#include "leaf-envelopes.h"
22 23
23 //==============================================================================24 //==============================================================================
24 25
@@ -216,10 +217,13 @@ extern "C" { · 191 unmodified lines
216 int iLast;217 int iLast;
217 int index;218 int index;
218 float period;219 float period;
220 float smoothPeriod;
219 221
220 uint16_t hopSize;222 uint16_t hopSize;
221 uint16_t windowSize;223 uint16_t windowSize;
222 uint8_t fba;224 uint8_t fba;
225
226 tExpSmooth smooth;
223 227
224 float timeConstant;228 float timeConstant;
225 float radius;229 float radius;
@@ -236,7 +240,9 @@ extern "C" { · 10 unmodified lines
236 void tPeriodDetection_initToPool (tPeriodDetection* const, float* in, float* out, int bufSize, int frameSize, tMempool* const);240 void tPeriodDetection_initToPool (tPeriodDetection* const, float* in, float* out, int bufSize, int frameSize, tMempool* const);
237 void tPeriodDetection_freeFromPool (tPeriodDetection* const, tMempool* const);241 void tPeriodDetection_freeFromPool (tPeriodDetection* const, tMempool* const);
238 242
239 float tPeriodDetection_findPeriod (tPeriodDetection* const, float sample);243 float tPeriodDetection_tick (tPeriodDetection* const, float sample);
244 float tPeriodDetection_getPeriod (tPeriodDetection* const);
245 void tPeriodDetection_setSmoothAmount (tPeriodDetection* const, float amount);
240 void tPeriodDetection_setHopSize (tPeriodDetection* p, int hs);246 void tPeriodDetection_setHopSize (tPeriodDetection* p, int hs);
241 void tPeriodDetection_setWindowSize (tPeriodDetection* p, int ws);247 void tPeriodDetection_setWindowSize (tPeriodDetection* p, int ws);
242 248
LEAF/Inc/leaf-effects.h+1−0
@@ -19,6 +19,7 @@ extern "C" { · 18 unmodified lines
19#include "leaf-mempool.h"19#include "leaf-mempool.h"
20#include "leaf-dynamics.h"20#include "leaf-dynamics.h"
21#include "leaf-analysis.h"21#include "leaf-analysis.h"
22#include "leaf-envelopes.h"
22 23
23 //==============================================================================24 //==============================================================================
24 25
LEAF/Src/leaf-analysis.c+22−29
@@ -840,36 +840,12 @@ static void snac_biasbuf(tSNAC* const snac) · 839 unmodified lines
840//===========================================================================840//===========================================================================
841void tPeriodDetection_init (tPeriodDetection* const pd, float* in, float* out, int bufSize, int frameSize)841void tPeriodDetection_init (tPeriodDetection* const pd, float* in, float* out, int bufSize, int frameSize)
842{842{
843 _tPeriodDetection* p = *pd = (_tPeriodDetection*) leaf_calloc(sizeof(_tPeriodDetection));843 tPeriodDetection_initToPool(pd, in, out, bufSize, frameSize, &leaf_mempool);
844
845 p->inBuffer = in;
846 p->outBuffer = out;
847 p->bufSize = bufSize;
848 p->frameSize = frameSize;
849 p->framesPerBuffer = p->bufSize / p->frameSize;
850 p->curBlock = 1;
851 p->lastBlock = 0;
852 p->index = 0;
853
854 p->hopSize = DEFHOPSIZE;
855 p->windowSize = DEFWINDOWSIZE;
856 p->fba = FBA;
857
858 tEnvPD_init(&p->env, p->windowSize, p->hopSize, p->frameSize);
859
860 tSNAC_init(&p->snac, DEFOVERLAP);
861
862 p->timeConstant = DEFTIMECONSTANT;
863 p->radius = expf(-1000.0f * p->hopSize * leaf.invSampleRate / p->timeConstant);
864}844}
865 845
866void tPeriodDetection_free (tPeriodDetection* const pd)846void tPeriodDetection_free (tPeriodDetection* const pd)
867{847{
868 _tPeriodDetection* p = *pd;848 tPeriodDetection_freeFromPool(pd, &leaf_mempool);
869
870 tEnvPD_free(&p->env);
871 tSNAC_free(&p->snac);
872 leaf_free(p);
873}849}
874 850
875void tPeriodDetection_initToPool (tPeriodDetection* const pd, float* in, float* out, int bufSize, int frameSize, tMempool* const mp)851void tPeriodDetection_initToPool (tPeriodDetection* const pd, float* in, float* out, int bufSize, int frameSize, tMempool* const mp)
@@ -894,6 +870,8 @@ void tPeriodDetection_initToPool (tPeriodDetection* const pd, float* in, flo · 18 unmodified lines
894 870
895 tSNAC_initToPool(&p->snac, DEFOVERLAP, mp);871 tSNAC_initToPool(&p->snac, DEFOVERLAP, mp);
896 872
873 tExpSmooth_initToPool(&p->smooth, 0.0f, 1.0f, mp);
874
897 p->timeConstant = DEFTIMECONSTANT;875 p->timeConstant = DEFTIMECONSTANT;
898 p->radius = expf(-1000.0f * p->hopSize * leaf.invSampleRate / p->timeConstant);876 p->radius = expf(-1000.0f * p->hopSize * leaf.invSampleRate / p->timeConstant);
899}877}
@@ -905,10 +883,11 @@ void tPeriodDetection_freeFromPool (tPeriodDetection* const pd, tMempoo · 5 unmodified lines
905 883
906 tEnvPD_freeFromPool(&p->env, mp);884 tEnvPD_freeFromPool(&p->env, mp);
907 tSNAC_freeFromPool(&p->snac, mp);885 tSNAC_freeFromPool(&p->snac, mp);
886 tExpSmooth_freeFromPool(&p->smooth, mp);
908 mpool_free(p, &m->pool);887 mpool_free(p, &m->pool);
909}888}
910 889
911float tPeriodDetection_findPeriod (tPeriodDetection* pd, float sample)890float tPeriodDetection_tick (tPeriodDetection* pd, float sample)
912{891{
913 _tPeriodDetection* p = *pd;892 _tPeriodDetection* p = *pd;
914 893
@@ -939,8 +918,22 @@ float tPeriodDetection_findPeriod (tPeriodDetection* pd, float sample) · 24 unmodified lines
939 if (p->lastBlock >= p->framesPerBuffer) p->lastBlock = 0;918 if (p->lastBlock >= p->framesPerBuffer) p->lastBlock = 0;
940 }919 }
941 920
942 // changed from period to p->period921 tExpSmooth_setDest(&p->smooth, p->period);
943 return p->period;922 p->smoothPeriod = tExpSmooth_tick(&p->smooth);
923 return p->smoothPeriod;
924}
925
926float tPeriodDetection_getPeriod(tPeriodDetection* pd)
927{
928 _tPeriodDetection* p = *pd;
929 return p->smoothPeriod;
930}
931
932void tPeriodDetection_setSmoothAmount(tPeriodDetection* pd, float amount)
933{
934 _tPeriodDetection* p = *pd;
935 LEAF_clip(0.0f, amount, 1.0f);
936 tExpSmooth_setFactor(&p->smooth, 1.0f - amount);
944}937}
945 938
946void tPeriodDetection_setHopSize(tPeriodDetection* pd, int hs)939void tPeriodDetection_setHopSize(tPeriodDetection* pd, int hs)
LEAF/Src/leaf-effects.c+11−99
@@ -963,7 +963,7 @@ float tPitchShift_shift (tPitchShift* psr) · 962 unmodified lines
963 963
964 if (p->indexstore >= ps->frameSize)964 if (p->indexstore >= ps->frameSize)
965 {965 {
966 period = p->period;966 period = tPeriodDetection_getPeriod(&p);
967 967
968 if(pitchshift_attackdetect(ps) == 1)968 if(pitchshift_attackdetect(ps) == 1)
969 {969 {
@@ -995,7 +995,7 @@ float tPitchShift_shiftToFreq (tPitchShift* psr, float freq) · 25 unmodified lines
995 995
996 if (p->indexstore >= ps->frameSize)996 if (p->indexstore >= ps->frameSize)
997 {997 {
998 period = p->period;998 period = tPeriodDetection_getPeriod(&p);
999 999
1000 if(pitchshift_attackdetect(ps) == 1)1000 if(pitchshift_attackdetect(ps) == 1)
1001 {1001 {
@@ -1030,7 +1030,7 @@ float tPitchShift_shiftToFunc (tPitchShift* psr, float (*fun)(float)) · 28 unmodified lines
1030 1030
1031 if (p->indexstore >= ps->frameSize)1031 if (p->indexstore >= ps->frameSize)
1032 {1032 {
1033 period = p->period;1033 period = tPeriodDetection_getPeriod(&p);
1034 1034
1035 if(pitchshift_attackdetect(ps) == 1)1035 if(pitchshift_attackdetect(ps) == 1)
1036 {1036 {
@@ -1060,54 +1060,12 @@ float tPitchShift_shiftToFunc (tPitchShift* psr, float (*fun)(float)) · 23 unmodified lines
1060 1060
1061void tRetune_init(tRetune* const rt, int numVoices, int bufSize, int frameSize)1061void tRetune_init(tRetune* const rt, int numVoices, int bufSize, int frameSize)
1062{1062{
1063 _tRetune* r = *rt = (_tRetune*) leaf_calloc(sizeof(_tRetune));1063 tRetune_initToPool(rt, numVoices, bufSize, frameSize, &leaf_mempool);
1064
1065 r->bufSize = bufSize;
1066 r->frameSize = frameSize;
1067 r->numVoices = numVoices;
1068
1069 r->inBuffer = (float*) leaf_calloc(sizeof(float) * r->bufSize);
1070 r->outBuffers = (float**) leaf_calloc(sizeof(float*) * r->numVoices);
1071
1072 r->hopSize = DEFHOPSIZE;
1073 r->windowSize = DEFWINDOWSIZE;
1074 r->fba = FBA;
1075 tRetune_setTimeConstant(rt, DEFTIMECONSTANT);
1076
1077 r->inputPeriod = 0.0f;
1078
1079 r->ps = (tPitchShift*) leaf_calloc(sizeof(tPitchShift) * r->numVoices);
1080 r->pitchFactor = (float*) leaf_calloc(sizeof(float) * r->numVoices);
1081 r->tickOutput = (float*) leaf_calloc(sizeof(float) * r->numVoices);
1082 for (int i = 0; i < r->numVoices; ++i)
1083 {
1084 r->outBuffers[i] = (float*) leaf_calloc(sizeof(float) * r->bufSize);
1085 }
1086
1087 tPeriodDetection_init(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize);
1088
1089 for (int i = 0; i < r->numVoices; ++i)
1090 {
1091 tPitchShift_init(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize);
1092 }
1093}1064}
1094 1065
1095void tRetune_free(tRetune* const rt)1066void tRetune_free(tRetune* const rt)
1096{1067{
1097 _tRetune* r = *rt;1068 tRetune_freeFromPool(rt, &leaf_mempool);
1098
1099 tPeriodDetection_free(&r->pd);
1100 for (int i = 0; i < r->numVoices; ++i)
1101 {
1102 tPitchShift_free(&r->ps[i]);
1103 leaf_free(r->outBuffers[i]);
1104 }
1105 leaf_free(r->tickOutput);
1106 leaf_free(r->pitchFactor);
1107 leaf_free(r->ps);
1108 leaf_free(r->inBuffer);
1109 leaf_free(r->outBuffers);
1110 leaf_free(r);
1111}1069}
1112 1070
1113void tRetune_initToPool (tRetune* const rt, int numVoices, int bufSize, int frameSize, tMempool* const mp)1071void tRetune_initToPool (tRetune* const rt, int numVoices, int bufSize, int frameSize, tMempool* const mp)
@@ -1138,6 +1096,7 @@ void tRetune_initToPool (tRetune* const rt, int numVoices, int bufSize, · 24 unmodified lines
1138 }1096 }
1139 1097
1140 tPeriodDetection_initToPool(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize, mp);1098 tPeriodDetection_initToPool(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize, mp);
1099 tPeriodDetection_setSmoothAmount(&r->pd, 0.0f);
1141 1100
1142 for (int i = 0; i < r->numVoices; ++i)1101 for (int i = 0; i < r->numVoices; ++i)
1143 {1102 {
@@ -1168,7 +1127,7 @@ float* tRetune_tick(tRetune* const rt, float sample) · 24 unmodified lines
1168{1127{
1169 _tRetune* r = *rt;1128 _tRetune* r = *rt;
1170 1129
1171 r->inputPeriod = tPeriodDetection_findPeriod(&r->pd, sample);1130 r->inputPeriod = tPeriodDetection_tick(&r->pd, sample);
1172 1131
1173 for (int v = 0; v < r->numVoices; ++v)1132 for (int v = 0; v < r->numVoices; ++v)
1174 {1133 {
@@ -1203,8 +1162,6 @@ void tRetune_setNumVoices(tRetune* const rt, int numVoices) · 28 unmodified lines
1203 r->outBuffers[i] = (float*) leaf_alloc(sizeof(float) * r->bufSize);1162 r->outBuffers[i] = (float*) leaf_alloc(sizeof(float) * r->bufSize);
1204 tPitchShift_init(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize);1163 tPitchShift_init(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize);
1205 }1164 }
1206
1207
1208}1165}
1209 1166
1210void tRetune_setPitchFactors(tRetune* const rt, float pf)1167void tRetune_setPitchFactors(tRetune* const rt, float pf)
@@ -1270,56 +1227,12 @@ float tRetune_getInputFreq(tRetune* const rt) · 59 unmodified lines
1270 1227
1271void tAutotune_init(tAutotune* const rt, int numVoices, int bufSize, int frameSize)1228void tAutotune_init(tAutotune* const rt, int numVoices, int bufSize, int frameSize)
1272{1229{
1273 _tAutotune* r = *rt = (_tAutotune*) leaf_alloc(sizeof(_tAutotune));1230 tAutotune_initToPool(rt, numVoices, bufSize, frameSize, &leaf_mempool);
1274
1275 r->bufSize = bufSize;
1276 r->frameSize = frameSize;
1277 r->numVoices = numVoices;
1278
1279 r->inBuffer = (float*) leaf_alloc(sizeof(float) * r->bufSize);
1280 r->outBuffers = (float**) leaf_alloc(sizeof(float*) * r->numVoices);
1281
1282 r->hopSize = DEFHOPSIZE;
1283 r->windowSize = DEFWINDOWSIZE;
1284 r->fba = FBA;
1285 tAutotune_setTimeConstant(rt, DEFTIMECONSTANT);
1286
1287
1288
1289 r->ps = (tPitchShift*) leaf_alloc(sizeof(tPitchShift) * r->numVoices);
1290 r->freq = (float*) leaf_alloc(sizeof(float) * r->numVoices);
1291 r->tickOutput = (float*) leaf_alloc(sizeof(float) * r->numVoices);
1292 for (int i = 0; i < r->numVoices; ++i)
1293 {
1294 r->outBuffers[i] = (float*) leaf_alloc(sizeof(float) * r->bufSize);
1295 }
1296
1297 tPeriodDetection_init(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize);
1298
1299 for (int i = 0; i < r->numVoices; ++i)
1300 {
1301 tPitchShift_init(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize);
1302 }
1303
1304 r->inputPeriod = 0.0f;
1305}1231}
1306 1232
1307void tAutotune_free(tAutotune* const rt)1233void tAutotune_free(tAutotune* const rt)
1308{1234{
1309 _tAutotune* r = *rt;1235 tAutotune_freeFromPool(rt, &leaf_mempool);
1310
1311 tPeriodDetection_free(&r->pd);
1312 for (int i = 0; i < r->numVoices; ++i)
1313 {
1314 tPitchShift_free(&r->ps[i]);
1315 leaf_free(r->outBuffers[i]);
1316 }
1317 leaf_free(r->tickOutput);
1318 leaf_free(r->freq);
1319 leaf_free(r->ps);
1320 leaf_free(r->inBuffer);
1321 leaf_free(r->outBuffers);
1322 leaf_free(r);
1323}1236}
1324 1237
1325void tAutotune_initToPool (tAutotune* const rt, int numVoices, int bufSize, int frameSize, tMempool* const mp)1238void tAutotune_initToPool (tAutotune* const rt, int numVoices, int bufSize, int frameSize, tMempool* const mp)
@@ -1339,8 +1252,6 @@ void tAutotune_initToPool (tAutotune* const rt, int numVoices, int buf · 13 unmodified lines
1339 r->fba = FBA;1252 r->fba = FBA;
1340 tAutotune_setTimeConstant(rt, DEFTIMECONSTANT);1253 tAutotune_setTimeConstant(rt, DEFTIMECONSTANT);
1341 1254
1342
1343
1344 r->ps = (tPitchShift*) mpool_alloc(sizeof(tPitchShift) * r->numVoices, &m->pool);1255 r->ps = (tPitchShift*) mpool_alloc(sizeof(tPitchShift) * r->numVoices, &m->pool);
1345 r->freq = (float*) mpool_alloc(sizeof(float) * r->numVoices, &m->pool);1256 r->freq = (float*) mpool_alloc(sizeof(float) * r->numVoices, &m->pool);
1346 r->tickOutput = (float*) mpool_alloc(sizeof(float) * r->numVoices, &m->pool);1257 r->tickOutput = (float*) mpool_alloc(sizeof(float) * r->numVoices, &m->pool);
@@ -1350,6 +1261,7 @@ void tAutotune_initToPool (tAutotune* const rt, int numVoices, int buf · 3 unmodified lines
1350 }1261 }
1351 1262
1352 tPeriodDetection_initToPool(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize, mp);1263 tPeriodDetection_initToPool(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize, mp);
1264 tPeriodDetection_setSmoothAmount(&r->pd, 0.5f);
1353 1265
1354 for (int i = 0; i < r->numVoices; ++i)1266 for (int i = 0; i < r->numVoices; ++i)
1355 {1267 {
@@ -1382,7 +1294,7 @@ float* tAutotune_tick(tAutotune* const rt, float sample) · 26 unmodified lines
1382{1294{
1383 _tAutotune* r = *rt;1295 _tAutotune* r = *rt;
1384 1296
1385 float tempPeriod = tPeriodDetection_findPeriod(&r->pd, sample);1297 float tempPeriod = tPeriodDetection_tick(&r->pd, sample);
1386 if (tempPeriod < 1000.0f) //to avoid trying to follow consonants JS1298 if (tempPeriod < 1000.0f) //to avoid trying to follow consonants JS
1387 {1299 {
1388 r->inputPeriod = tempPeriod;1300 r->inputPeriod = tempPeriod;
LEAF_JUCEPlugin/Source/MyTest.cpp+33−25
@@ -25,6 +25,8 @@ tSampler samp; · 24 unmodified lines
25tBuffer buff;25tBuffer buff;
26tEnvelope env;26tEnvelope env;
27 27
28tAutotune at;
29
28float gain;30float gain;
29float freq;31float freq;
30float dtime;32float dtime;
@@ -43,19 +45,21 @@ void LEAFTest_init (float sampleRate, int blockSize) · 12 unmodified lines
43 45
44 tNoise_init(&noise, WhiteNoise);46 tNoise_init(&noise, WhiteNoise);
45 47
46 tSVF_init(&bp1, SVFTypeBandpass, 100, 4.0f);48 tAutotune_init(&at, 1, 1024, 512);
47 tSVF_init(&bp2, SVFTypeBandpass, 1000, 4.0f);
48
49 tFormantShifter_init(&fs, 20);
50
51 // Init and set record
52 tBuffer_init (&buff, leaf.sampleRate); // init, 1 second buffer
53 tBuffer_setRecordMode (&buff, RecordOneShot); // RecordOneShot records once through
54 49
55 // Init and set play50// tSVF_init(&bp1, SVFTypeBandpass, 100, 4.0f);
56 tSampler_init (&samp, &buff); // init, give address of record buffer51// tSVF_init(&bp2, SVFTypeBandpass, 1000, 4.0f);
57 tSampler_setMode (&samp, PlayLoop); //set in Loop Mode52//
58 tSampler_setRate(&samp, 1.763f); // Rate of 1.053// tFormantShifter_init(&fs, 20);
54//
55// // Init and set record
56// tBuffer_init (&buff, leaf.sampleRate); // init, 1 second buffer
57// tBuffer_setRecordMode (&buff, RecordOneShot); // RecordOneShot records once through
58//
59// // Init and set play
60// tSampler_init (&samp, &buff); // init, give address of record buffer
61// tSampler_setMode (&samp, PlayLoop); //set in Loop Mode
62// tSampler_setRate(&samp, 1.763f); // Rate of 1.0
59}63}
60 64
61float LEAFTest_tick (float input)65float LEAFTest_tick (float input)
@@ -66,28 +70,32 @@ float LEAFTest_tick (float input) · 4 unmodified lines
66// b += tSVF_tick(&bp2, sample);70// b += tSVF_tick(&bp2, sample);
67//71//
68// return (tFormantShifter_tick(&fs, input));72// return (tFormantShifter_tick(&fs, input));
73//
74// tBuffer_tick(&buff, input);
75
76// return tSampler_tick(&samp);
69 77
70 tBuffer_tick(&buff, input);78 tAutotune_setFreq(&at, 440.0f, 0);
71 79
72 return tSampler_tick(&samp);80 return tAutotune_tick(&at, input)[0];
73}81}
74 82
75int firstFrame = 1;83int firstFrame = 1;
76bool lastState = false, lastPlayState = false;84bool lastState = false, lastPlayState = false;
77void LEAFTest_block (void)85void LEAFTest_block (void)
78{86{
79 if (firstFrame == 1)87// if (firstFrame == 1)
80 {88// {
81 tBuffer_record(&buff); // starts recording89// tBuffer_record(&buff); // starts recording
82 tSampler_play(&samp); // start spitting samples out90// tSampler_play(&samp); // start spitting samples out
83 firstFrame = 0;91// firstFrame = 0;
84 }92// }
85 93
86 float val = getSliderValue("mod freq");94 float val = getSliderValue("mod freq");
87 95
88 x = val * 3.5f + 0.5f;96 x = val * 3.5f + 0.5f;
89 97
90 a = val * tBuffer_getBufferLength(&buff);98// a = val * tBuffer_getBufferLength(&buff);
91 99
92 DBG("start: " + String(a));100 DBG("start: " + String(a));
93 101
@@ -95,12 +103,12 @@ void LEAFTest_block (void) · 1 unmodified line
95 103
96 y = val * 49.0f + 1.0f;104 y = val * 49.0f + 1.0f;
97 b = val * 20.0f - 5.0f;105 b = val * 20.0f - 5.0f;
98 b = val * tBuffer_getBufferLength(&buff);106// b = val * tBuffer_getBufferLength(&buff);
99 107
100 DBG("rate: " + String(b));108 DBG("rate: " + String(b));
101 109//
102 tSampler_setStart(&samp, a);110// tSampler_setStart(&samp, a);
103 tSampler_setEnd(&samp, b);111// tSampler_setEnd(&samp, b);
104// tSampler_setRate(&samp, b);112// tSampler_setRate(&samp, b);
105 113
106// tFormantShifter_setShiftFactor(&fs, x);114// tFormantShifter_setShiftFactor(&fs, x);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t